1 /*
2  * $Id: vldap.c 1014 2011-02-03 16:04:37Z volz0r $
3  * Copyright (C) 1999-2009 Inter7 Internet Technologies, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18  */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <pwd.h>
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <time.h>
28 #include <utime.h>
29 #include <lber.h>
30 #include <ldap.h>
31 #include "config.h"
32 #include "vpopmail.h"
33 #include "vauth.h"
34 #include "vlimits.h"
35 #include "vldap.h"
36 
37 LDAP *ld = NULL;
38 LDAPMessage *glm = NULL;
39 
40 #ifdef CLEAR_PASS
41 #  define NUM_LDAP_FIELDS  9
42 #else
43 #  define NUM_LDAP_FIELDS  8
44 #endif
45 
46 char *ldap_fields[NUM_LDAP_FIELDS] = {
47                                          "uid",   /* 0 pw_name   */
48                                          "userPassword",  /* 1 pw_passwd */
49                                          "qmailUID",   /* 2 pw_uid    */
50                                          "qmailGID",   /* 3 pw_gid    */
51                                          "qmaildomain",  /* 4 pw_gecos  */
52                                          "mailMessageStore",  /* 5 pw_dir    */
53                                          "mailQuota",   /* 6 pw_shell  */
54 #ifndef CLEAR_PASS
55                                          "objectclass"   /* 7 ldap      */
56 #else
57                                          "clearPassword",  /* 7 pw_clear_passwd */
58                                          "objectclass"   /* 8 ldap      */
59 #endif
60                                      };
61 
62 /***************************************************************************/
63 
64 /*
65  * get ldap connection info
66  */
load_connection_info()67 int load_connection_info() {
68     FILE *fp;
69     char conn_info[256];
70     char config[256];
71     int eof;
72     static int loaded = 0;
73     char *port;
74     char delimiters[] = "|\n";
75     char *conf_read;
76 
77     if (loaded) return 0;
78     loaded = 1;
79 
80     sprintf(config, "%s/etc/%s", VPOPMAILDIR, "vpopmail.ldap");
81 
82     fp = fopen(config, "r");
83     if (fp == NULL) {
84         fprintf(stderr, "vldap: can't read settings from %s\n", config);
85         return(VA_NO_AUTH_CONNECTION);
86     }
87 
88     /* skip comments and blank lines */
89     do {
90         eof = (fgets (conn_info, sizeof(conn_info), fp) == NULL);
91     } while (!eof && ((*conn_info == '#') || (*conn_info == '\n')));
92 
93     if (eof) {
94         /* no valid data read, return error */
95         fprintf(stderr, "vldap: no valid settings in %s\n", config);
96         return(VA_NO_AUTH_CONNECTION);
97     }
98 
99     conf_read = strdup(conn_info);
100     VLDAP_SERVER = strtok(conf_read, delimiters);
101     if (VLDAP_SERVER == NULL) return VA_PARSE_ERROR;
102     port = strtok(NULL, delimiters);
103     if (port == NULL) return VA_PARSE_ERROR;
104     VLDAP_PORT = atoi(port);
105     VLDAP_USER = strtok(NULL, delimiters);
106     if (VLDAP_USER == NULL) return VA_PARSE_ERROR;
107     VLDAP_PASSWORD = strtok(NULL, delimiters);
108     if (VLDAP_PASSWORD == NULL) return VA_PARSE_ERROR;
109     VLDAP_BASEDN = strtok(NULL, delimiters);
110     if (VLDAP_BASEDN == NULL) return VA_PARSE_ERROR;
111 
112     return 0;
113 }
114 
vauth_getpw(char * user,char * domain)115 struct vqpasswd *vauth_getpw(char *user, char *domain) {
116     int ret = 0;
117     size_t len = 0;
118     struct vqpasswd *vpw = NULL;
119     LDAPMessage *res = NULL, *msg = NULL;
120     char *filter = NULL, **vals = NULL, *h = NULL, *t = NULL, *passwd = NULL;
121     char *dn = NULL;
122     uid_t myuid;
123     uid_t uid;
124     gid_t gid;
125 
126     verrori = 0;
127     lowerit(user);
128     lowerit(domain);
129 
130     vget_assign(domain,NULL,0,&uid,&gid);
131 
132     myuid = geteuid();
133     if ( myuid != 0 && myuid != uid ) {
134         return(NULL);
135     }
136 
137     /* connect to the ldap server (if we havent already got a connection open) */
138     if (ld == NULL ) {
139         if (ldap_connect() != 0) {
140             safe_free((void **) &filter);
141             return NULL;
142         }
143     }
144 
145     /* take a given domain, and set dn to be this format :
146      * ou=somedomain.com,o=vpopmail
147      */
148     if (compose_dn(&dn,domain) != 0)
149         return NULL;
150 
151     /* take the username and create set filter ot be in this format :
152      * (&(objectclass=qmailUser)(uid=someusername))
153      */
154     len = (strlen(user) + 32 + 1);
155     filter = (char *)safe_malloc(len);
156     memset((char *)filter, 0, len);
157     snprintf(filter, len, "(&(objectclass=qmailUser)(uid=%s))", user);
158 
159     /* perform an ldap search
160      * int ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res)
161      *
162      * Will search synchronously, and not return until the operation completes.
163      * base : DN of the entry at which to start the search
164      * scope : scope of the search
165      *   LDAP_SCOPE_SUBTREE means to search the object and all of its descendents.
166      * filter : filter to apply to the search
167      * attrs : attribute types to return from entries that match filter
168      * attrsonly : set to 0 for attributes and attributetypes are wanted. 1 if only attributes are wanted.
169      */
170     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
171                         filter, vldap_attrs, 0, &res);
172 
173     safe_free((void **) &filter);
174 
175     /* see if the search ran without generating an error */
176     if (ret != LDAP_SUCCESS ) {
177         ldap_perror(ld,"Error");
178         return NULL;
179     }
180 
181     /* grab a pointer to the 1st entry in the chain of search results */
182     msg = ldap_first_entry(ld, res);
183     if (msg == NULL) {
184         /* We had an error grabbing the pointer */
185         return NULL;
186     }
187 
188     /* find out how many matches we found */
189     ret = ldap_count_entries(ld, msg);
190     if (ret == -1 ) {
191         /* an error occurred when counting the entries */
192         ldap_perror(ld,"Error");
193         return NULL;
194     }
195 
196 
197     /*
198        Fetch userPassword first so we can make sure
199        we're able to handle it's password encryption (if any)
200     */
201 
202     /* userPasswd / pw_password */
203 
204     vals = ldap_get_values(ld, msg, "userPassword");
205     if (vals == NULL) {
206         ldap_perror(ld,"Error");
207         return NULL;
208     }
209 
210     t = h = NULL;
211 
212     passwd = (char *)safe_malloc((strlen(*vals) + 1));
213 
214     memset((char *)passwd, 0, (strlen(*vals) + 1));
215     memcpy((char *)passwd, (char *)(*vals), strlen(*vals));
216 
217     if (*passwd == '{') {
218         for (t = h = (passwd + 1); *t; t++) {
219             if (*t == '}') {
220                 *t++ = '\0';
221 
222                 /* This is not the best, but we keep the pointer as (h - 1) */
223                 passwd = t;
224 
225                 /*
226                    Check against the encryption method, and if we see something
227                    we dont recognize or support, invalidate user login.
228                    vol@inter7.com
229                 */
230 
231                 /* Steki <steki@verat.net> Thu Jan 24 17:27:18 CET 2002
232                  *  Added check for MD5 crypted passwords
233                  */
234 
235                 if (strcmp(h, "crypt")&& strcmp(h, "MD5")) {
236                     free(h - 1);
237                     ldap_value_free(vals);
238                     return NULL;
239                 }
240                 break;
241             }
242         }
243         /*
244            No terminating brace found, or empty password.
245            vol@inter7.com
246         */
247         if (!(*t)) {
248             ldap_value_free(vals);
249             return NULL;
250         }
251     }
252 
253     /* create a vpw struct, which we will populate with the data we suck in from ldap */
254     vpw = (struct vqpasswd *) safe_malloc(sizeof(struct vqpasswd));
255     memset((struct vqpasswd *)vpw, 0, sizeof(struct vqpasswd));
256 
257     vpw->pw_passwd = (char *)safe_malloc((strlen(passwd) + 1));
258     memset((char *)vpw->pw_passwd, 0, (strlen(passwd) + 1));
259     memcpy((char *)vpw->pw_passwd, (char *)(passwd), strlen(passwd));
260 
261     if (vpw->pw_passwd == NULL) {
262         free(h - 1);
263         ldap_value_free(vals);
264         return NULL;
265     }
266 
267     /*
268        Old passwd pointer.
269        ..and don't forget to check if you even set the pointer *smack*
270 
271        vol@inter7.com
272     */
273     if (h)
274         free(h - 1);
275 
276     ldap_value_free(vals);
277 
278 
279     /* uid / pw_name */
280     vals = ldap_get_values(ld, msg, "uid");
281     if (vals == NULL) {
282         safe_free((void **) &vpw->pw_passwd);
283         ldap_perror(ld,"Error");
284         return NULL;
285     }
286     vpw->pw_name = (char *)safe_malloc((strlen(*vals) + 1));
287     memset((char *)vpw->pw_name, 0, (strlen(*vals) + 1));
288     memcpy((char *)vpw->pw_name, (char *)(*vals), strlen(*vals));
289     ldap_value_free(vals);
290 
291 
292     /* mailQuota / pw_shell */
293     vals = ldap_get_values(ld, msg, "mailQuota");
294     if (vals)
295         vpw->pw_shell = (char *)safe_malloc((strlen(*vals) + 1));
296     else
297         vpw->pw_shell = (char *)safe_malloc(1);
298 
299     if (vals) {
300         memset((char *)vpw->pw_shell, 0, (strlen(*vals) + 1));
301         memcpy((char *)vpw->pw_shell, (char *)(*vals), strlen(*vals));
302         ldap_value_free(vals);
303     } else {
304         *vpw->pw_shell = '\0';
305         ldap_perror(ld,"Error");
306     }
307 
308 
309     /* qmaildomain / pw_gecos */
310     vals = ldap_get_values(ld, msg, "qmaildomain");
311     if ( vals ) {
312         vpw->pw_gecos = (char *)safe_malloc((strlen(*vals) + 1));
313 
314         memset((char *)vpw->pw_gecos, 0, (strlen(*vals) + 1));
315         memcpy((char *)vpw->pw_gecos, (char *)(*vals), strlen(*vals));
316         ldap_value_free(vals);
317     } else
318         ldap_perror(ld,"Error");
319 
320 
321     /* mailMessageStore / pw_dir */
322     vals = ldap_get_values(ld, msg, "mailMessageStore");
323     if ( vals ) {
324         vpw->pw_dir = (char *)safe_malloc((strlen(*vals) + 1));
325 
326         memset((char *)vpw->pw_dir, 0, (strlen(*vals) + 1));
327         memcpy((char *)vpw->pw_dir, (char *)(*vals), strlen(*vals));
328         ldap_value_free(vals);
329     } else
330         ldap_perror(ld,"Error");
331 
332 
333     /* qmailUID / pw_uid */
334     vals = ldap_get_values(ld, msg, "qmailUID");
335     if ( vals ) {
336         vpw->pw_uid = atoi(*vals);
337         ldap_value_free(vals);
338     } else
339         ldap_perror(ld,"Error");
340 
341 
342     /* qmailGID / pw_gid */
343     vals = ldap_get_values(ld, msg, "qmailGID");
344     if ( vals ) {
345         vpw->pw_gid = atoi(*vals);
346         ldap_value_free(vals);
347     } else
348         ldap_perror(ld,"Error");
349 
350 #ifdef CLEAR_PASS
351     /* clearPasswd /  pw_clear_passwd */
352     vals = ldap_get_values(ld, msg, "clearPassword");
353     if ( vals ) {
354         vpw->pw_clear_passwd = (char *)safe_malloc((strlen(*vals) + 1));
355         memset((char *)vpw->pw_clear_passwd, 0, (strlen(*vals) + 1));
356         memcpy((char *)vpw->pw_clear_passwd, (char *)(*vals), strlen(*vals));
357         ldap_value_free(vals);
358     }
359 #endif
360 
361 
362     vlimits_setflags (vpw, domain);
363 
364     return vpw;
365 
366 }
367 
368 /***************************************************************************/
369 
vauth_end_getall()370 void vauth_end_getall() {}
371 
372 /***************************************************************************/
373 
vauth_getall(char * domain,int first,int sortit)374 struct vqpasswd *vauth_getall(char *domain, int first, int sortit) {
375     int ret = 0;
376     size_t len = 0;
377     struct vqpasswd *pw = NULL;
378     LDAPMessage *res = NULL;
379     char *filter = NULL, **vals = NULL;
380     char *basedn = NULL;
381 
382     /* if 1st time through, extract all users from this chosen domain */
383     if (first) {
384         lowerit(domain);
385 
386         len = (32 + 1);
387 
388         filter = (char *)safe_malloc(len);
389 
390         memset((char *)filter, 0, len);
391 
392         /* connect to the ldap server if we havent already done so */
393         if (ld == NULL ) {
394             if (ldap_connect() != 0) {
395                 safe_free((void **) &filter);
396                 return NULL;
397             }
398         }
399 
400         /* set basedn to be of the format :
401          *   ou=somedomain,o=vpopmail
402          */
403         if (compose_dn(&basedn,domain) != 0)  {
404             safe_free((void **) &filter);
405             return NULL;
406         }
407 
408         snprintf(filter, len, "(objectclass=qmailUser)");
409 
410         /* perform the lookup for all users in a given domain */
411         ret = ldap_search_s(ld, basedn, LDAP_SCOPE_SUBTREE,
412                             filter, vldap_attrs, 0, &res);
413 
414         safe_free((void **) &basedn);
415         safe_free((void **) &filter);
416 
417         if (ret != LDAP_SUCCESS) {
418             ldap_perror(ld,"Error");
419             return NULL;
420         }
421 
422         /* sort the entries alphabetically by username if required */
423         if ( sortit ) {
424             if ( ldap_sort_entries( ld, &res, "uid", &strcasecmp ) != 0)  {
425                 ldap_perror(ld,"Error");
426                 return NULL;
427             }
428 
429             if (ret != LDAP_SUCCESS)
430                 return NULL;
431         }
432 
433         /* get a pointer to the first user in the list */
434         glm = ldap_first_entry(ld, res);
435         if (glm == NULL)
436             return NULL;
437 
438         /* grab the ldap properties of this user */
439         vals = ldap_get_values(ld, glm, "uid");
440         if (vals == NULL) {
441             ldap_perror(ld,"Error");
442             return NULL;
443         }
444 
445         /* grab the vpopmail properties of this user */
446         pw = vauth_getpw(*vals, domain);
447 
448         return pw;
449     }
450     else {
451         /* not 1st time through, so get next entry from the chain */
452         if (glm == NULL)  /* Just to be safe. (vol@inter7.com) */
453             return NULL;
454 
455         res = glm;
456 
457         glm = ldap_next_entry(ld, res);
458         if (glm == NULL)
459             return NULL;
460 
461         vals = ldap_get_values(ld, glm, "uid");
462         if (vals == NULL) {
463             ldap_perror(ld,"Error");
464             return NULL;
465         }
466 
467         pw = vauth_getpw(*vals, domain);
468 
469         ldap_value_free(vals);
470 
471         return pw;
472     }
473 }
474 
475 /***************************************************************************/
476 
477 /*
478    Higher-level functions no longer crypt.
479    Lame.
480 
481    vol@inter7.com
482 */
vauth_adduser(char * user,char * domain,char * password,char * gecos,char * dir,int apop)483 int vauth_adduser(char *user, char *domain, char *password, char *gecos, char *dir, int apop ) {
484     char *dn = NULL;
485     char *dn_tmp = NULL;
486     LDAPMod **lm = NULL;
487     char dom_dir[156];
488     uid_t uid;
489     gid_t gid;
490     int ret = 0, vd = 0;
491     int i,len;
492     char *b = NULL;
493     char crypted[100] = { 0 };
494 
495 
496     if ((dir) && (*dir))
497         vd = 1;
498 
499     if ( gecos==0 || gecos[0]==0)
500         gecos=user;
501 
502     /* take a given domain, and lookup the dom_dir, uid, gid */
503     if ( vget_assign(domain, dom_dir, 156, &uid, &gid ) == NULL ) {
504         fprintf(stderr, "failed to vget_assign the domain : %s", domain);
505         return (-1);
506     }
507 
508     if (vd) {
509         ret = strlen(dom_dir) + 5 + strlen(dir) + strlen(user);
510     } else {
511         ret = strlen(dom_dir) + 5 + strlen(user);
512     }
513 
514     b = (char *)safe_malloc(ret);
515 
516     memset((char *)b, 0, ret);
517 
518     if (vd) {
519         snprintf(b, ret, "%s/%s/%s", dom_dir, dir, user);
520     } else {
521         snprintf(b, ret, "%s/%s", dom_dir, user);
522     }
523 
524     dir = b;
525 
526     /* make an ldap connection (unless we already have one open) */
527     if (ld == NULL ) {
528         if (ldap_connect() != 0)
529             return -99;
530     }
531 
532     lm = (LDAPMod **)safe_malloc(sizeof(LDAPMod *) * (NUM_LDAP_FIELDS +1));
533 
534     for(i=0;i<NUM_LDAP_FIELDS;++i) {
535         lm[i] = (LDAPMod *)safe_malloc(sizeof(LDAPMod));
536 
537         memset((LDAPMod *)lm[i], 0, sizeof(LDAPMod));
538         lm[i]->mod_op = LDAP_MOD_ADD;
539         lm[i]->mod_type = safe_strdup(ldap_fields[i]);
540         lm[i]->mod_values = (char **)safe_malloc(sizeof(char *) * 2);
541         lm[i]->mod_values[1] = NULL;
542     }
543 
544     lm[NUM_LDAP_FIELDS] = NULL;
545 
546     /* lm[0] will store : uid / pw_name */
547     lm[0]->mod_values[0] = safe_strdup(user);
548 
549     /* lm[1] will store : userPassword / pw_password */
550     memset((char *)crypted, 0, 100);
551     if ( password[0] == 0 ) {
552         crypted[0] = 0;
553     } else {
554         mkpasswd3(password, crypted, 100);
555     }
556 
557     lm[1]->mod_values[0] = (char *) safe_malloc(strlen(crypted) + 7 + 1);
558 #ifdef MD5_PASSWORDS
559 
560     snprintf(lm[1]->mod_values[0], strlen(crypted) + 7 + 1, "{MD5}%s", crypted);
561 #else
562 
563     snprintf(lm[1]->mod_values[0], strlen(crypted) + 7 + 1, "{crypt}%s", crypted);
564 #endif
565 
566     /* lm[2] will store : qmailUID / pw_uid */
567     lm[2]->mod_values[0] = (char *) safe_malloc(10);
568     if ( apop == USE_POP )
569         sprintf(lm[2]->mod_values[0], "%d", 1 );
570     else
571         sprintf(lm[2]->mod_values[0], "%d", 2 );
572 
573     /* lm[3] will store : qmailGID / pw_gid */
574     lm[3]->mod_values[0] = (char *) safe_malloc(10);
575     sprintf(lm[3]->mod_values[0], "%d", 0);
576 
577     /* lm[4] will store : qmaildomain / pw_gecos */
578     lm[4]->mod_values[0] = safe_strdup(gecos);
579 
580     /* lm[5] will store : mailMessageStore / pw_dir */
581     lm[5]->mod_values[0] = safe_strdup(dir);
582 
583     /* lm[6] will store : mailQuota / pw_shell */
584     lm[6]->mod_values[0] = safe_strdup("NOQUOTA");
585 
586     /* When running with clearpasswords enabled,
587      * lm[7] will store : clearPassword / pw_clear_password
588      */
589 #ifdef CLEAR_PASS
590     /* with clear passwords,
591      * lm[7] will store : clearPassword / pw_clear_password
592      * lm[8] will store : objectclass
593      */
594     lm[7]->mod_values[0] = strdup(password);
595     lm[8]->mod_values[0] = safe_strdup("qmailUser");
596 #else
597     /* without clear passwords,
598     * lm[7] will store : objectclass
599     */
600     lm[7]->mod_values[0] = safe_strdup("qmailUser");
601 #endif
602 
603     /* set dn_tmp to be of the format :
604      *   ou=somedomain.com,o=vpopmail
605      */
606     if (compose_dn(&dn_tmp,domain) != 0) {
607         for(i=0;i<8;++i) {
608             safe_free((void **) &lm[i]->mod_type);
609             safe_free((void **) &lm[i]->mod_values[0]);
610         }
611         safe_free((void **) &lm);
612         safe_free((void **) &dn);
613         return -98;
614     }
615 
616     /* set dn to be of the format :
617      *   uid=someuser, ou=somedomain,o=vpopmail
618      */
619     len = 4 + strlen(user) + 2 + strlen(VLDAP_BASEDN) + 4 + strlen(domain) + 1;
620     dn = (char *) safe_malloc(len);
621     memset((char *)dn, 0, len);
622     snprintf(dn, len, "uid=%s, %s", user, dn_tmp);
623     safe_free((void **) &dn_tmp);
624 
625     /* add object to ldap
626      *   dn is the DN of the entry to add
627      *   lm is the attributes of the entry to add
628      */
629     ret = ldap_add_s(ld, dn, lm);
630     safe_free((void **) &dn);
631 
632     for(i=0;i<NUM_LDAP_FIELDS;++i) {
633         safe_free((void **) &lm[i]->mod_type);
634         safe_free((void **) &lm[i]->mod_values[0]);
635     }
636 
637     safe_free((void **) &lm);
638 
639     if (ret != LDAP_SUCCESS) {
640         ldap_perror(ld,"Error");
641         if (ret == LDAP_ALREADY_EXISTS)
642             return VA_USERNAME_EXISTS;
643         return -99;
644     }
645     return VA_SUCCESS;
646 }
647 
648 /***************************************************************************/
649 
vauth_adddomain(char * domain)650 int vauth_adddomain( char *domain ) {
651     int ret = 0;
652     char *dn = NULL;
653     LDAPMod **lm = NULL;
654 
655     /* make a connection to the ldap server, if we are not already connected */
656     if (ld == NULL ) {
657         ret = ldap_connect();
658         if (ret != 0) {
659             return -99;
660             /* Attention I am not quite shure, when we return NULL or -99, see above */
661         }
662     }
663 
664     lm = (LDAPMod **)safe_malloc(sizeof(LDAPMod *) * 3);
665 
666     lm[0] = (LDAPMod *)safe_malloc(sizeof(LDAPMod));
667 
668     lm[1] = (LDAPMod *)safe_malloc(sizeof(LDAPMod));
669     lm[2] = NULL;
670 
671     memset((LDAPMod *)lm[0], 0, sizeof(LDAPMod));
672     memset((LDAPMod *)lm[1], 0, sizeof(LDAPMod));
673 
674     lm[0]->mod_op = LDAP_MOD_ADD;
675     lm[1]->mod_op = LDAP_MOD_ADD;
676 
677     lm[0]->mod_type = safe_strdup("ou");
678     lm[1]->mod_type = safe_strdup("objectclass");
679 
680     lm[0]->mod_values = (char **)safe_malloc(sizeof(char *) * 2);
681     lm[1]->mod_values = (char **)safe_malloc(sizeof(char *) * 2);
682 
683     lm[0]->mod_values[1] = NULL;
684     lm[1]->mod_values[1] = NULL;
685 
686     lm[0]->mod_values[0] = safe_strdup(domain);
687     lm[1]->mod_values[0] = safe_strdup("organizationalUnit");
688 
689     /* set dn to be of the format :
690      *   ou=somedomain.com,o=vpopmail
691      */
692     if (compose_dn(&dn,domain) != 0 ) {
693         safe_free((void **) &lm[0]->mod_type);
694         safe_free((void **) &lm[1]->mod_type);
695         safe_free((void **) &lm[0]->mod_values[0]);
696         safe_free((void **) &lm[1]->mod_values[0]);
697         safe_free((void **) &lm[1]);
698         safe_free((void **) &lm[0]);
699         safe_free((void **) &lm);
700         return -98;
701     }
702 
703     /* dn will be ou=somedomain.com,o=vpopmail
704      * lm will be the ldap propoerties of somedomain.com
705      */
706     ret = ldap_add_s(ld, dn, lm);
707 
708     if (ret != LDAP_SUCCESS) {
709         ldap_perror(ld,"Error");
710         return -99;
711     }
712 
713     safe_free((void **) &dn);
714     safe_free((void **) &lm[0]->mod_type);
715     safe_free((void **) &lm[1]->mod_type);
716     safe_free((void **) &lm[0]->mod_values[0]);
717     safe_free((void **) &lm[1]->mod_values[0]);
718     safe_free((void **) &lm[2]);
719     safe_free((void **) &lm[1]);
720     safe_free((void **) &lm[0]);
721     safe_free((void **) &lm);
722 
723     if (ret != LDAP_SUCCESS) {
724         if (ret == LDAP_ALREADY_EXISTS)
725             return VA_USERNAME_EXISTS;
726         return -99;
727     }
728 
729     return VA_SUCCESS;
730 }
731 
732 /***************************************************************************/
733 
vauth_deldomain(char * domain)734 int vauth_deldomain( char *domain ) {
735     int ret = 0;
736     size_t len = 0;
737     char *dn = NULL;
738     struct vqpasswd *pw = NULL;
739 
740     /* make a connection to the ldap server, if we dont have one already */
741     if (ld == NULL ) {
742         if (ldap_connect() != 0)
743             return -99;
744     }
745 
746     len = strlen(domain) + strlen(VLDAP_BASEDN) + 4 + 1;
747 
748     /* dn will be of the format :
749      *   ou=somedomain.com,o=vpopmail
750      */
751     if (compose_dn(&dn,domain) != 0)
752         return -98;
753 
754     /* loop through all the users in the domain, deleting each one */
755     for (pw = vauth_getall(domain, 1, 0); pw; pw = vauth_getall(domain, 0, 0))
756         vauth_deluser(pw->pw_name, domain);
757 
758     /* next, delete the actual domain */
759     ret = ldap_delete_s(ld, dn);
760     safe_free((void **) &dn);
761 
762     if (ret != LDAP_SUCCESS ) {
763         ldap_perror(ld,"Error");
764         return -99;
765     }
766 
767 #ifdef VALIAS
768 	valias_delete_domain(domain);
769 #endif
770 
771     return VA_SUCCESS;
772 }
773 
774 /***************************************************************************/
775 
vauth_vpasswd(char * user,char * domain,char * crypted,int apop)776 int vauth_vpasswd( char *user, char *domain, char *crypted, int apop ) {
777     int ret = 0;
778     struct vqpasswd *pw = NULL;
779 
780     pw = vauth_getpw(user, domain);
781     if (pw == NULL)
782         return VA_USER_DOES_NOT_EXIST;
783 
784     pw->pw_passwd = safe_strdup(crypted);
785 
786     ret = vauth_setpw(pw, domain);
787 
788     return ret;
789 }
790 
791 /***************************************************************************/
792 
vauth_deluser(char * user,char * domain)793 int vauth_deluser( char *user, char *domain ) {
794     int ret = 0;
795     size_t len = 0;
796     char *dn = NULL;
797     char *dn_tmp = NULL;
798 
799     /* make a connection to the ldap server if we dont have one already */
800     if (ld == NULL ) {
801         if (ldap_connect() != 0)
802             return -99;
803     }
804 
805     len = 4 + strlen(user) + 2 + strlen(VLDAP_BASEDN) + 4 + strlen(domain) + 1;
806 
807     /* make dn_tmp to be of the format
808      *  ou=somedomain.com,o=vpopmail
809      */
810     if (compose_dn(&dn_tmp,domain) != 0)
811         return -98;
812 
813     dn = (char *)safe_malloc(len);
814     memset((char *)dn, 0, len);
815 
816     /* make dn to be of the format
817      *   uid=someuser, ou=somedomain.com,o=vpopmail
818      */
819     snprintf(dn, len, "uid=%s, %s", user, dn_tmp);
820     safe_free((void **) &dn_tmp);
821 
822     /* delete the user */
823     ret = ldap_delete_s(ld, dn);
824 
825     safe_free((void **) &dn);
826 
827     if (ret != LDAP_SUCCESS) {
828         ldap_perror(ld,"Error");
829         return -99;
830     }
831 
832     return VA_SUCCESS;
833 }
834 
835 /***************************************************************************/
836 
vauth_setquota(char * username,char * domain,char * quota)837 int vauth_setquota( char *username, char *domain, char *quota) {
838     int ret = 0;
839     struct vqpasswd *pw = NULL;
840 
841     if ( strlen(username) > MAX_PW_NAME )
842         return(VA_USER_NAME_TOO_LONG);
843 #ifdef USERS_BIG_DIR
844 
845     if ( strlen(username) == 1 )
846         return(VA_ILLEGAL_USERNAME);
847 #endif
848 
849     if ( strlen(domain) > MAX_PW_DOMAIN )
850         return(VA_DOMAIN_NAME_TOO_LONG);
851     if ( strlen(quota) > MAX_PW_QUOTA )
852         return(VA_QUOTA_TOO_LONG);
853 
854     pw = vauth_getpw(username, domain);
855     if ( (pw == NULL) && (verrori != 0))
856         return verrori;
857     else if ( pw == NULL )
858         return VA_USER_DOES_NOT_EXIST;
859 
860     pw->pw_shell = safe_strdup(quota);
861 
862     ret = vauth_setpw(pw, domain);
863 
864     return ret;
865 }
866 
867 /***************************************************************************/
868 
vauth_setpw(struct vqpasswd * inpw,char * domain)869 int vauth_setpw( struct vqpasswd *inpw, char *domain ) {
870     int ret = 0;
871     size_t len = 0;
872     char *dn = NULL;
873     char *dn_tmp = NULL;
874     LDAPMod **lm = NULL;
875     int i;
876 #ifdef SQWEBMAIL_PASS
877 
878     uid_t uid;
879     gid_t gid;
880 #endif
881 
882     ret = vcheck_vqpw(inpw, domain);
883     if ( ret != 0 ) {
884         return(ret);
885     }
886 
887     if (ld == NULL ) {
888         if (ldap_connect() != 0)
889             return -99;
890     }
891 
892     lm = (LDAPMod **)malloc(sizeof(LDAPMod *) * NUM_LDAP_FIELDS + 1);
893     for(i=0;i<NUM_LDAP_FIELDS;++i) {
894         lm[i] = (LDAPMod *)safe_malloc(sizeof(LDAPMod));
895         memset((LDAPMod *)lm[i], 0, sizeof(LDAPMod));
896         lm[i]->mod_op = LDAP_MOD_REPLACE;
897         lm[i]->mod_values = (char **)safe_malloc(sizeof(char *) * 2);
898         lm[i]->mod_values[1] = NULL;
899         lm[i]->mod_type = safe_strdup(ldap_fields[i]);
900     }
901     lm[NUM_LDAP_FIELDS] = NULL;
902 
903     lm[0]->mod_values[0] = safe_strdup(inpw->pw_name);
904 
905     lm[1]->mod_values[0] = safe_malloc(strlen(inpw->pw_passwd) + 7 + 1);
906 #ifdef MD5_PASSWORDS
907 
908     snprintf(lm[1]->mod_values[0], strlen(inpw->pw_passwd) + 7 + 1, "{MD5}%s", inpw->pw_passwd);
909 #else
910 
911     snprintf(lm[1]->mod_values[0], strlen(inpw->pw_passwd) + 7 + 1, "{crypt}%s", inpw->pw_passwd);
912 #endif
913 
914     lm[2]->mod_values[0] = (char *)safe_malloc(10);
915     sprintf(lm[2]->mod_values[0], "%d", inpw->pw_uid);
916 
917     lm[3]->mod_values[0] = (char *) safe_malloc(10);
918     sprintf(lm[3]->mod_values[0], "%d", inpw->pw_gid);
919 
920     if ( inpw->pw_gecos == NULL) {
921         lm[4]->mod_values[0] = safe_strdup("");
922     } else {
923         lm[4]->mod_values[0] = safe_strdup(inpw->pw_gecos);
924     }
925     lm[5]->mod_values[0] = safe_strdup(inpw->pw_dir);
926     lm[6]->mod_values[0] = safe_strdup(inpw->pw_shell);
927 #ifdef CLEAR_PASS
928 
929     lm[7]->mod_values[0] = safe_strdup(inpw->pw_clear_passwd);
930 #endif
931 
932     lm[NUM_LDAP_FIELDS-1]->mod_values[0] = strdup("qmailUser");
933 
934 
935     if (compose_dn(&dn_tmp,domain) != 0 ) {
936         safe_free((void **) &lm);
937         return -98;
938     }
939 
940     len = 4 + strlen(inpw->pw_name) + 2 + strlen(VLDAP_BASEDN) + 4 + strlen(domain) + 1;
941     dn = (char *) safe_malloc (len);
942     memset((char *)dn, 0, len);
943 
944     snprintf(dn, len, "uid=%s, %s", inpw->pw_name, dn_tmp);
945 
946     ret = ldap_modify_s(ld, dn, lm);
947     safe_free((void **) &dn);
948 
949     for(i=0;i<NUM_LDAP_FIELDS;++i)
950         safe_free((void **) &lm);
951 
952     if (ret != LDAP_SUCCESS) {
953         ldap_perror(ld,"Error");
954         return -99;
955     }
956     /* MARK */
957 #ifdef SQWEBMAIL_PASS
958     vget_assign(domain, NULL, 0, &uid, &gid );
959     vsqwebmail_pass( inpw->pw_dir, inpw->pw_passwd, uid, gid);
960 #endif
961 
962 #ifdef ONCHANGE_SCRIPT
963     if( allow_onchange ) {
964        /* tell other programs that data has changed */
965        snprintf ( onchange_buf, MAX_BUFF, "%s@%s", inpw->pw_name, domain );
966        call_onchange ( "mod_user" );
967        }
968 #endif
969 
970     return VA_SUCCESS;
971 }
972 
973 /***************************************************************************/
974 
975 /*   Verify the connection to the authentication database   */
976 
vauth_open(int will_update)977 int vauth_open( int will_update ) {
978 
979 #ifdef VPOPMAIL_DEBUG
980 show_trace = ( getenv("VPSHOW_TRACE") != NULL);
981 show_query = ( getenv("VPSHOW_QUERY") != NULL);
982 dump_data  = ( getenv("VPDUMP_DATA")  != NULL);
983 #endif
984 
985 #ifdef VPOPMAIL_DEBUG
986     if( show_trace ) {
987         fprintf( stderr, "vauth_open()\n");
988     }
989 #endif
990 
991 
992 
993 /*
994  *  If the connection to this authentication database can fail
995  *  you should test access here.  If it works, return 0, else
996  *  return VA_NO_AUTH_CONNECTION.  You can also set the string
997  *  sqlerr to some short descriptive text about the problem,
998  *  and allocate a much longer string, pointed to by last_query
999  *  that can be displayed in an error message returned because
1000  *  of this problem.
1001  *
1002  */
1003 
1004     return( 0 );
1005 }
1006 
1007 /***************************************************************************/
1008 
vclose(void)1009 void vclose(void) {
1010     if (ld) {
1011         ldap_unbind_s(ld);
1012         ld = NULL;
1013     }
1014 }
1015 
1016 /***************************************************************************/
1017 
dc_filename(char * domain,uid_t uid,gid_t gid)1018 char *dc_filename(char *domain, uid_t uid, gid_t gid)
1019 {
1020  static char dir_control_file[MAX_DIR_NAME];
1021  struct passwd *pw;
1022 
1023     /* if we are lucky the domain is in the assign file */
1024     if ( vget_assign(domain,dir_control_file,MAX_DIR_NAME,NULL,NULL)!=NULL ) {
1025         strncat(dir_control_file, "/.dir-control", MAX_DIR_NAME);
1026 
1027     /* it isn't in the assign file so we have to get it from /etc/passwd */
1028     } else {
1029 
1030         /* save some time if this is the vpopmail user */
1031         if ( uid == VPOPMAILUID ) {
1032             strncpy(dir_control_file, VPOPMAILDIR, MAX_DIR_NAME);
1033 
1034         /* for other users, look them up in /etc/passwd */
1035         } else if ( (pw=getpwuid(uid))!=NULL ) {
1036             strncpy(dir_control_file, pw->pw_dir, MAX_DIR_NAME);
1037 
1038         /* all else fails return a blank string */
1039         } else {
1040             return("");
1041         }
1042 
1043         /* stick on the rest of the path */
1044         strncat(dir_control_file, "/" DOMAINS_DIR "/.dir-control", MAX_DIR_NAME);
1045     }
1046     return(dir_control_file);
1047 }
1048 
vread_dir_control(vdir_type * vdir,char * domain,uid_t uid,gid_t gid)1049 int vread_dir_control(vdir_type *vdir, char *domain, uid_t uid, gid_t gid)
1050 {
1051  FILE *fs;
1052  char dir_control_file[MAX_DIR_NAME];
1053  int i;
1054 
1055     strncpy(dir_control_file,dc_filename(domain, uid, gid),MAX_DIR_NAME);
1056 
1057 
1058     if ( (fs = fopen(dir_control_file, "r")) == NULL ) {
1059         vdir->cur_users = 0;
1060         for(i=0;i<MAX_DIR_LEVELS;++i){
1061             vdir->level_start[i] = 0;
1062             vdir->level_end[i] = MAX_DIR_LIST-1;
1063             vdir->level_index[i] = 0;
1064         }
1065         vdir->level_mod[0] = 0;
1066         vdir->level_mod[1] = 2;
1067         vdir->level_mod[2] = 4;
1068         vdir->level_cur = 0;
1069         vdir->level_max = MAX_DIR_LEVELS;
1070         vdir->the_dir[0] = 0;
1071         return(-1);
1072     }
1073 
1074     fgets(dir_control_file, MAX_DIR_NAME, fs );
1075     vdir->cur_users = atol(dir_control_file);
1076 
1077     fgets(dir_control_file, MAX_DIR_NAME, fs );
1078     vdir->level_cur = atoi(dir_control_file);
1079 
1080     fgets(dir_control_file, MAX_DIR_NAME, fs );
1081     vdir->level_max = atoi(dir_control_file);
1082 
1083     fgets(dir_control_file, MAX_DIR_NAME, fs );
1084     vdir->level_start[0] = atoi(dir_control_file);
1085     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1086     vdir->level_start[1] = atoi(&dir_control_file[i]);
1087     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1088     vdir->level_start[2] = atoi(&dir_control_file[i]);
1089 
1090     fgets(dir_control_file, MAX_DIR_NAME, fs );
1091     vdir->level_end[0] = atoi(dir_control_file);
1092     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1093     vdir->level_end[1] = atoi(&dir_control_file[i]);
1094     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1095     vdir->level_end[2] = atoi(&dir_control_file[i]);
1096 
1097     fgets(dir_control_file, MAX_DIR_NAME, fs );
1098     vdir->level_mod[0] = atoi(dir_control_file);
1099     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1100     vdir->level_mod[1] = atoi(&dir_control_file[i]);
1101     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1102     vdir->level_mod[2] = atoi(&dir_control_file[i]);
1103 
1104     fgets(dir_control_file, MAX_DIR_NAME, fs );
1105     vdir->level_index[0] = atoi(dir_control_file);
1106     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1107     vdir->level_index[1] = atoi(&dir_control_file[i]);
1108     for(i=0;dir_control_file[i]!=' ';++i); ++i;
1109     vdir->level_index[2] = atoi(&dir_control_file[i]);
1110 
1111     fgets(dir_control_file, MAX_DIR_NAME, fs );
1112     for(i=0;dir_control_file[i]!=0;++i) {
1113         if (dir_control_file[i] == '\n') {
1114             dir_control_file[i] = 0;
1115         }
1116     }
1117 
1118     fgets(dir_control_file, MAX_DIR_NAME, fs );
1119     for(i=0;dir_control_file[i]!=0;++i) {
1120         if (dir_control_file[i] == '\n') {
1121             dir_control_file[i] = 0;
1122         }
1123     }
1124     strncpy(vdir->the_dir, dir_control_file, MAX_DIR_NAME);
1125 
1126     fclose(fs);
1127 
1128     return(0);
1129 }
1130 
vwrite_dir_control(vdir_type * vdir,char * domain,uid_t uid,gid_t gid)1131 int vwrite_dir_control(vdir_type *vdir, char *domain, uid_t uid, gid_t gid)
1132 {
1133  FILE *fs;
1134  char dir_control_file[MAX_DIR_NAME];
1135  char dir_control_tmp_file[MAX_DIR_NAME];
1136 
1137     strncpy(dir_control_file,dc_filename(domain, uid, gid),MAX_DIR_NAME);
1138     snprintf(dir_control_tmp_file, MAX_DIR_NAME,
1139         "%s.%d", dir_control_file, getpid());
1140 
1141     if ( (fs = fopen(dir_control_tmp_file, "w+")) == NULL ) {
1142         return(-1);
1143     }
1144 
1145     fprintf(fs, "%lu\n", vdir->cur_users);
1146     fprintf(fs, "%d\n", vdir->level_cur);
1147     fprintf(fs, "%d\n", vdir->level_max);
1148     fprintf(fs, "%d %d %d\n",
1149         vdir->level_start[0],
1150         vdir->level_start[1],
1151         vdir->level_start[2]);
1152     fprintf(fs, "%d %d %d\n",
1153         vdir->level_end[0],
1154         vdir->level_end[1],
1155         vdir->level_end[2]);
1156     fprintf(fs, "%d %d %d\n",
1157         vdir->level_mod[0],
1158         vdir->level_mod[1],
1159         vdir->level_mod[2]);
1160     fprintf(fs, "%d %d %d\n",
1161         vdir->level_index[0],
1162         vdir->level_index[1],
1163         vdir->level_index[2]);
1164     fprintf(fs, "%s\n", vdir->the_dir);
1165 
1166     fclose(fs);
1167 
1168     rename( dir_control_tmp_file, dir_control_file);
1169 
1170     chown(dir_control_file,uid, gid);
1171 
1172     return(0);
1173 }
1174 
vdel_dir_control(char * domain)1175 int vdel_dir_control(char *domain)
1176 {
1177  char dir_control_file[MAX_DIR_NAME];
1178 
1179     vget_assign(domain, dir_control_file, 156, NULL,NULL);
1180     strncat(dir_control_file,"/.dir-control", MAX_DIR_NAME);
1181     return(unlink(dir_control_file));
1182 }
1183 
1184 /***************************************************************************/
1185 
1186 #ifdef ENABLE_AUTH_LOGGING
vset_lastauth_time(char * user,char * domain,char * remoteip,time_t cur_time)1187 int vset_lastauth_time(char *user, char *domain, char *remoteip, time_t cur_time ) {
1188     char *tmpbuf;
1189     FILE *fs;
1190     struct vqpasswd *vpw;
1191     struct utimbuf ubuf;
1192     uid_t uid;
1193     gid_t gid;
1194 
1195     if ((vpw = vauth_getpw( user, domain )) == NULL)
1196         return (0);
1197 
1198     tmpbuf = (char *) safe_malloc(MAX_BUFF);
1199     sprintf(tmpbuf, "%s/lastauth", vpw->pw_dir);
1200     if ( (fs = fopen(tmpbuf,"w+")) == NULL ) {
1201         safe_free((void **) &tmpbuf);
1202         return(-1);
1203     }
1204     fprintf(fs, "%s", remoteip);
1205     fclose(fs);
1206     ubuf.actime = cur_time;
1207     ubuf.modtime = cur_time;
1208     utime(tmpbuf, &ubuf);
1209     vget_assign(domain,NULL,0,&uid,&gid);
1210     chown(tmpbuf,uid,gid);
1211     safe_free((void **) &tmpbuf);
1212     return(0);
1213 }
1214 
1215 
vset_lastauth(char * user,char * domain,char * remoteip)1216 int vset_lastauth(char *user, char *domain, char *remoteip ) {
1217     return(vset_lastauth_time(user, domain, remoteip, time(NULL) ));
1218 }
1219 
1220 
vget_lastauth(struct vqpasswd * pw,char * domain)1221 time_t vget_lastauth( struct vqpasswd *pw, char *domain) {
1222     char *tmpbuf;
1223     struct stat mystatbuf;
1224 
1225     tmpbuf = (char *) safe_malloc(MAX_BUFF);
1226     sprintf(tmpbuf, "%s/lastauth", pw->pw_dir);
1227     if ( stat(tmpbuf,&mystatbuf) == -1 ) {
1228         safe_free((void **) &tmpbuf);
1229         return(0);
1230     }
1231     safe_free((void **) &tmpbuf);
1232     return(mystatbuf.st_mtime);
1233 }
1234 
1235 
vget_lastauthip(struct vqpasswd * pw,char * domain)1236 char *vget_lastauthip( struct vqpasswd *pw, char *domain) {
1237     static char tmpbuf[MAX_BUFF];
1238     FILE *fs;
1239 
1240     snprintf(tmpbuf, MAX_BUFF, "%s/lastauth", pw->pw_dir);
1241     if ( (fs=fopen(tmpbuf,"r"))==NULL)
1242         return(NULL);
1243     fgets(tmpbuf,MAX_BUFF,fs);
1244     fclose(fs);
1245     return(tmpbuf);
1246 }
1247 #endif /* ENABLE_AUTH_LOGGING */
1248 
1249 /***************************************************************************/
1250 
1251 #ifdef IP_ALIAS_DOMAINS
vget_ip_map(char * ip,char * domain,int domain_size)1252 int vget_ip_map( char *ip, char *domain, int domain_size) {
1253     FILE *fs;
1254     char tmpbuf[156];
1255     char *tmpstr;
1256 
1257     if ( ip == NULL || strlen(ip) <= 0 )
1258         return(-1);
1259 
1260     /* open the ip_alias_map file */
1261     snprintf(tmpbuf, 156, "%s/%s", VPOPMAILDIR, IP_ALIAS_MAP_FILE);
1262     if ( (fs = fopen(tmpbuf,"r")) == NULL )
1263         return(-1);
1264 
1265     while( fgets(tmpbuf, 156, fs) != NULL ) {
1266         tmpstr = strtok(tmpbuf, IP_ALIAS_TOKENS);
1267         if ( tmpstr == NULL )
1268             continue;
1269         if ( strcmp(ip, tmpstr) != 0 )
1270             continue;
1271 
1272         tmpstr = strtok(NULL, IP_ALIAS_TOKENS);
1273         if ( tmpstr == NULL )
1274             continue;
1275         strncpy(domain, tmpstr, domain_size);
1276         fclose(fs);
1277         return(0);
1278 
1279     }
1280     fclose(fs);
1281     return(-1);
1282 }
1283 
1284 /***************************************************************************/
1285 
1286 /*
1287  * Add an ip to domain mapping
1288  * It will remove any duplicate entry before adding it
1289  *
1290  */
vadd_ip_map(char * ip,char * domain)1291 int vadd_ip_map( char *ip, char *domain) {
1292     FILE *fs;
1293     char tmpbuf[156];
1294 
1295     if ( ip == NULL || strlen(ip) <= 0 )
1296         return(-1);
1297     if ( domain == NULL || strlen(domain) <= 0 )
1298         return(-10);
1299 
1300     vdel_ip_map( ip, domain );
1301 
1302     snprintf(tmpbuf, 156, "%s/%s", VPOPMAILDIR, IP_ALIAS_MAP_FILE);
1303     if ( (fs = fopen(tmpbuf,"a+")) == NULL )
1304         return(-1);
1305     fprintf( fs, "%s %s\n", ip, domain);
1306     fclose(fs);
1307 
1308     return(0);
1309 }
1310 
vdel_ip_map(char * ip,char * domain)1311 int vdel_ip_map( char *ip, char *domain) {
1312     FILE *fs;
1313     FILE *fs1;
1314     char file1[156];
1315     char file2[156];
1316     char tmpbuf[156];
1317     char tmpbuf1[156];
1318     char *ip_f;
1319     char *domain_f;
1320 
1321     if ( ip == NULL || strlen(ip) <= 0 )
1322         return(-1);
1323     if ( domain == NULL || strlen(domain) <= 0 )
1324         return(-1);
1325 
1326     snprintf(file1, 156, "%s/%s", VPOPMAILDIR, IP_ALIAS_MAP_FILE);
1327     if ( (fs = fopen(file1,"r")) == NULL )
1328         return(-1);
1329 
1330     snprintf(file2, 156,
1331              "%s/%s.%d", VPOPMAILDIR, IP_ALIAS_MAP_FILE, getpid());
1332     if ( (fs1 = fopen(file2,"w")) == NULL ) {
1333         fclose(fs);
1334         return(-1);
1335     }
1336 
1337     while( fgets(tmpbuf, 156, fs) != NULL ) {
1338         strncpy(tmpbuf1,tmpbuf, 156);
1339 
1340         ip_f = strtok(tmpbuf, IP_ALIAS_TOKENS);
1341         if ( ip_f == NULL )
1342             continue;
1343 
1344         domain_f = strtok(NULL, IP_ALIAS_TOKENS);
1345         if ( domain_f == NULL )
1346             continue;
1347 
1348         if ( strcmp(ip, ip_f) == 0 && strcmp(domain,domain_f) == 0)
1349             continue;
1350 
1351         fprintf(fs1, tmpbuf1);
1352 
1353     }
1354     fclose(fs);
1355     fclose(fs1);
1356 
1357     if ( rename( file2, file1) < 0 )
1358         return(-1);
1359 
1360     return(0);
1361 }
1362 
vshow_ip_map(int first,char * ip,char * domain)1363 int vshow_ip_map( int first, char *ip, char *domain) {
1364     static FILE *fs = NULL;
1365     char tmpbuf[156];
1366     char *tmpstr;
1367 
1368     if ( ip == NULL )
1369         return(-1);
1370     if ( domain == NULL )
1371         return(-1);
1372 
1373     if ( first == 1 ) {
1374         if ( fs != NULL ) {
1375             fclose(fs);
1376             fs = NULL;
1377         }
1378         snprintf(tmpbuf, 156, "%s/%s", VPOPMAILDIR, IP_ALIAS_MAP_FILE);
1379         if ( (fs = fopen(tmpbuf,"r")) == NULL )
1380             return(-1);
1381     }
1382     if ( fs == NULL )
1383         return(-1);
1384 
1385     while (1) {
1386         if (fgets(tmpbuf, 156, fs) == NULL ) {
1387             fclose(fs);
1388             fs = NULL;
1389             return(0);
1390         }
1391 
1392         tmpstr = strtok(tmpbuf, IP_ALIAS_TOKENS);
1393         if ( tmpstr == NULL )
1394             continue;
1395         strcpy( ip, tmpstr);
1396 
1397         tmpstr = strtok(NULL, IP_ALIAS_TOKENS);
1398         if ( tmpstr == NULL )
1399             continue;
1400         strcpy( domain, tmpstr);
1401 
1402         return(1);
1403     }
1404     return(-1);
1405 
1406 }
1407 #endif
1408 
1409 /***************************************************************************/
1410 
1411 /* take a given domain, and set dn to be a string of this format :
1412  * ou=somedomain,o=vpopmail
1413  */
compose_dn(char ** dn,char * domain)1414 int compose_dn (char **dn, char *domain) {
1415     size_t len = 0;
1416 
1417     len = strlen(domain) + strlen(VLDAP_BASEDN) + 5;
1418 
1419     *dn = (char *)safe_malloc(len);
1420     memset((char *)*dn, 0, len);
1421 
1422     snprintf(*dn,len,"ou=%s,%s",domain,VLDAP_BASEDN);
1423 
1424     return 0;
1425 
1426 }
1427 
1428 /***************************************************************************/
1429 
ldap_connect()1430 int ldap_connect () {
1431     int ret = 0;
1432 
1433     /* Set verror here and unset it when successful, is ok, because if one of these
1434     three steps fail the whole auth_connection failed */
1435     verrori = load_connection_info();
1436     if (verrori) return -1;
1437 
1438     ld = ldap_init(VLDAP_SERVER, VLDAP_PORT);
1439     if (ld == NULL) {
1440         ldap_perror(ld,"Failed to inititialize LDAP-Connection");
1441         return -99;
1442     }
1443     ret = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldapversion );
1444     if (ret != LDAP_OPT_SUCCESS) {
1445         ldap_perror(ld,"Failed to set LDAP-Option");
1446         return -99;
1447     }
1448     ret = ldap_simple_bind_s(ld, VLDAP_USER, VLDAP_PASSWORD);
1449     if (ret != LDAP_SUCCESS) {
1450         ldap_perror(ld,"Error");
1451         return (VA_NO_AUTH_CONNECTION);
1452     }
1453 
1454     verrori = 0;
1455     return VA_SUCCESS;
1456 }
1457 
1458 /***************************************************************************/
1459 
safe_free(void ** p)1460 void safe_free (void **p) {
1461     if (*p) {
1462         free (*p);
1463         *p = 0;
1464     }
1465 }
1466 
1467 /***************************************************************************/
1468 
safe_strdup(const char * s)1469 char *safe_strdup (const char *s) {
1470     char *p;
1471     size_t l;
1472 
1473     if (!s || !*s)
1474         return 0;
1475     l = strlen (s) + 1;
1476     p = (char *)safe_malloc (l);
1477     memcpy (p, s, l);
1478     return (p);
1479 }
1480 
1481 /***************************************************************************/
1482 
safe_malloc(size_t siz)1483 void *safe_malloc (size_t siz) {
1484     void *p;
1485 
1486     if (siz == 0)
1487         return 0;
1488     if ((p = (void *) malloc (siz)) == 0) {
1489         printf("No more memory...exiting\n");
1490         exit (1);
1491     }
1492     return (p);
1493 }
1494 
1495 /***************************************************************************/
1496 
vauth_crypt(char * user,char * domain,char * clear_pass,struct vqpasswd * vpw)1497 int vauth_crypt(char *user,char *domain,char *clear_pass,struct vqpasswd *vpw) {
1498     if ( vpw == NULL )
1499         return(-1);
1500 
1501     return(strcmp(crypt(clear_pass,vpw->pw_passwd),vpw->pw_passwd));
1502 }
1503 
1504 /***************************************************************************/
1505 
1506 
1507 #ifdef VALIAS
1508 struct linklist *valias_current = NULL;
1509 
1510 
1511 /************************************************************************/
valias_select(char * alias,char * domain)1512 char *valias_select( char *alias, char *domain )
1513 {
1514  int err, len, ret, i = 0;
1515  char filter[512] = { 0 }, dn[512] = { 0 };
1516  struct linklist *temp_entry = NULL;
1517  LDAPMessage *res = NULL, *msg = NULL;
1518  char **aa = NULL, **di = NULL, *fields[] = { "aa", "di", NULL }, *p = NULL;
1519 
1520     /* remove old entries as necessary */
1521     while (valias_current != NULL)
1522         valias_current = linklist_del (valias_current);
1523 
1524    if (ld == NULL) {
1525 	  err = ldap_connect();
1526 	  if (err)
1527 		 return NULL;
1528    }
1529 
1530    memset(filter, 0, sizeof(filter));
1531    snprintf(filter, sizeof(filter), "(aa=%s@%s)", strcasecmp(alias, domain) ? alias : "*", domain);
1532 
1533    memset(dn, 0, sizeof(dn));
1534    snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
1535 
1536     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
1537                         filter, fields, 0, &res);
1538 
1539     if (ret != LDAP_SUCCESS ) {
1540         ldap_perror(ld,"Error");
1541         return NULL;
1542     }
1543 
1544     /* grab a pointer to the 1st entry in the chain of search results */
1545     msg = ldap_first_entry(ld, res);
1546     if (msg == NULL) {
1547         /* We had an error grabbing the pointer */
1548         return NULL;
1549     }
1550 
1551     /* find out how many matches we found */
1552     ret = ldap_count_entries(ld, msg);
1553     if (ret == -1 ) {
1554         /* an error occurred when counting the entries */
1555         ldap_perror(ld,"Error");
1556 		ldap_msgfree(res);
1557         return NULL;
1558     }
1559 
1560 	while(msg) {
1561 	   aa = ldap_get_values(ld, msg, "aa");
1562 	   if (aa == NULL) {
1563 		  fprintf(stderr, "vldap: warning: no address entry\n");
1564 		  msg = ldap_next_entry(ld, msg);
1565 		  continue;
1566 	   }
1567 
1568 	   di = ldap_get_values(ld, msg, "di");
1569 	   if (di == NULL) {
1570 		  fprintf(stderr, "vldap: warning: no delivery entries for '%s'\n", *aa);
1571 		  ldap_value_free(aa);
1572 	      msg = ldap_next_entry(ld, msg);
1573 		  continue;
1574 	   }
1575 
1576 	   for (p = *aa; *p; p++) {
1577 		  if (*p == '@') {
1578 			 *p = '\0';
1579 			 break;
1580 		  }
1581 	   }
1582 
1583 	   for (i = 0; di[i]; i++) {
1584 		   temp_entry = linklist_add(temp_entry, di[i], "");
1585 			if (valias_current == NULL)
1586 			   valias_current = temp_entry;
1587 	   }
1588 
1589 	   ldap_value_free(aa);
1590 	   ldap_value_free(di);
1591 	   msg = ldap_next_entry(ld, msg);
1592     }
1593 
1594     if (valias_current == NULL) return NULL; /* no results */
1595     else {
1596 		ldap_msgfree(res);
1597         return(valias_current->data);
1598     }
1599 }
1600 
1601 
1602 /************************************************************************/
valias_select_next()1603 char *valias_select_next()
1604 {
1605     if (valias_current == NULL) return NULL;
1606 
1607     valias_current = linklist_del (valias_current);
1608 
1609     if (valias_current == NULL) return NULL;
1610     else return valias_current->data;
1611 }
1612 
1613 
1614 /************************************************************************/
valias_insert(char * alias,char * domain,char * alias_line)1615 int valias_insert( char *alias, char *domain, char *alias_line)
1616 {
1617  int err, ret = 0, mod = LDAP_MOD_ADD, i = 0;
1618  LDAPMessage *msg = NULL, *res = NULL;
1619  LDAPMod **lm = NULL;
1620  char filter[512] = { 0 }, dn[512] = { 0 }, *fields[] = { "aa", NULL }, ud[512] = { 0 };
1621 
1622    if (ld == NULL) {
1623       if ( (err=ldap_connect()) != 0 )
1624 		 return(err);
1625    }
1626 
1627     while(*alias_line==' ' && *alias_line!=0) ++alias_line;
1628 
1629 	memset(ud, 0, sizeof(ud));
1630 	snprintf(ud, sizeof(ud), "%s@%s", alias, domain);
1631 
1632 	/*
1633 		 Check for existing entry to determine LDAP modification
1634 		 type
1635     */
1636 
1637 	memset(dn, 0, sizeof(dn));
1638 	snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
1639 
1640 	memset(filter, 0, sizeof(filter));
1641 	snprintf(filter, sizeof(filter), "aa=%s", ud);
1642 
1643     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
1644                         filter, fields, 0, &res);
1645 
1646     if (ret != LDAP_SUCCESS ) {
1647         ldap_perror(ld,"Error");
1648         return -1;
1649     }
1650 
1651     msg = ldap_first_entry(ld, res);
1652 
1653     if (msg == NULL)
1654 	   mod = LDAP_MOD_ADD;
1655 	else
1656 	   mod = LDAP_MOD_REPLACE;
1657 
1658 	ldap_msgfree(res);
1659 
1660 	memset(dn, 0, sizeof(dn));
1661 	snprintf(dn, sizeof(dn), "aa=%s,ou=valias,%s", ud, VLDAP_BASEDN);
1662 
1663 	lm = malloc(sizeof(LDAPMod *) * 4);
1664 	if (lm == NULL) {
1665 	   fprintf(stderr, "vldap: malloc failed\n");
1666 	   return -1;
1667 	}
1668 
1669 	for (i = 0; i < 3; i++) {
1670 	  lm[i] = malloc(sizeof(LDAPMod));
1671 	  if (lm[i] == NULL) {
1672 	     fprintf(stderr, "vldap: malloc failed\n");
1673 		 return -1;
1674 	  }
1675 
1676 	  memset(lm[i], 0, sizeof(LDAPMod));
1677 
1678 	  lm[i]->mod_op = mod;
1679 	  lm[i]->mod_values = malloc(sizeof(char *) * 2);
1680 	  lm[i]->mod_values[0] = NULL;
1681 	  lm[i]->mod_values[1] = NULL;
1682     }
1683 
1684     lm[0]->mod_type = safe_strdup("objectClass");
1685 	lm[0]->mod_values[0] = safe_strdup("valias");
1686 
1687     lm[1]->mod_type = safe_strdup("aa");
1688 	lm[1]->mod_values[0] = safe_strdup(ud);
1689 
1690     lm[2]->mod_op = LDAP_MOD_ADD;
1691     lm[2]->mod_type = safe_strdup("di");
1692 	lm[2]->mod_values[0] = safe_strdup(alias_line);
1693 
1694 	lm[3] = NULL;
1695 
1696 	if (mod == LDAP_MOD_ADD)
1697 	  ret = ldap_add_s(ld, dn, lm);
1698     else
1699 	   ret = ldap_modify_s(ld, dn, lm);
1700 
1701 	for (i = 0; i < 3; i++) {
1702 	  free(lm[i]->mod_type);
1703 	  free(lm[i]->mod_values[1]);
1704 	  free(lm[i]);
1705     }
1706 
1707 	free(lm);
1708 
1709 	if (ret != LDAP_SUCCESS) {
1710         ldap_perror(ld,"Error");
1711         return -1;
1712     }
1713 
1714 #ifdef ONCHANGE_SCRIPT
1715     if( allow_onchange ) {
1716        /* tell other programs that data has changed */
1717        snprintf ( onchange_buf, MAX_BUFF, "%s@%s - %s", alias, domain, alias_line );
1718        call_onchange ( "valias_insert" );
1719        }
1720 #endif
1721 
1722     return(0);
1723 }
1724 
1725 
1726 /************************************************************************/
valias_remove(char * alias,char * domain,char * alias_line)1727 int valias_remove( char *alias, char *domain, char *alias_line)
1728 {
1729  int err, ret = 0, i = 0;
1730  LDAPMod **lm = NULL;
1731  LDAPMessage *res = NULL, *msg = NULL;
1732  char **di = NULL, *fields[] = { "di", NULL };
1733  char ud[512] = { 0 }, dn[512] = { 0 }, filter[512] = { 0 };
1734 
1735     if ( (err=ldap_connect()) != 0 ) return(err);
1736 
1737 #ifdef ONCHANGE_SCRIPT
1738     if( allow_onchange ) {
1739        /* tell other programs that data has changed */
1740        snprintf ( onchange_buf, MAX_BUFF, "%s@%s - %s", alias, domain, alias_line );
1741        call_onchange ( "valias_remove" );
1742        }
1743 #endif
1744 
1745 	memset(ud, 0, sizeof(ud));
1746 	snprintf(ud, sizeof(ud), "%s@%s", alias, domain);
1747 
1748 	memset(dn, 0, sizeof(dn));
1749 	snprintf(dn, sizeof(dn), "aa=%s,ou=valias,%s", ud, VLDAP_BASEDN);
1750 
1751 	lm = malloc(sizeof(LDAPMod *) * 2);
1752 	if (lm == NULL) {
1753 	   fprintf(stderr, "vldap: malloc failed\n");
1754 	   return -1;
1755 	}
1756 
1757 	for (i = 0; i < 1; i++) {
1758 	  lm[i] = malloc(sizeof(LDAPMod));
1759 	  if (lm[i] == NULL) {
1760 	     fprintf(stderr, "vldap: malloc failed\n");
1761 		 return -1;
1762 	  }
1763 
1764 	  memset(lm[i], 0, sizeof(LDAPMod));
1765 
1766 	  lm[i]->mod_op = LDAP_MOD_DELETE;
1767 	  lm[i]->mod_values = malloc(sizeof(char *) * 2);
1768 	  lm[i]->mod_values[0] = NULL;
1769 	  lm[i]->mod_values[1] = NULL;
1770     }
1771 
1772     lm[0]->mod_type = safe_strdup("di");
1773 	lm[0]->mod_values[0] = safe_strdup(alias_line);
1774 
1775 	lm[1] = NULL;
1776 
1777     ret = ldap_modify_s(ld, dn, lm);
1778 
1779 	for (i = 0; i < 1; i++) {
1780 	  free(lm[i]->mod_type);
1781 	  free(lm[i]->mod_values[0]);
1782 	  free(lm[i]);
1783     }
1784 
1785 	free(lm);
1786 
1787 	if (ret != LDAP_SUCCESS) {
1788         ldap_perror(ld,"Error");
1789         return -1;
1790     }
1791 
1792 	/*
1793 	    If there are no delivery instructions left, delete
1794 		entry entirely
1795     */
1796 
1797 	memset(dn, 0, sizeof(dn));
1798 	snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
1799 
1800 	memset(filter, 0, sizeof(filter));
1801 	snprintf(filter, sizeof(filter), "aa=%s", ud);
1802 
1803     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE, filter, fields, 0, &res);
1804 	if (ret != LDAP_SUCCESS) {
1805 	   ldap_perror(ld, "Error");
1806 	   return -1;
1807     }
1808 
1809     msg = ldap_first_entry(ld, res);
1810 	if (msg == NULL) {
1811 	   ldap_perror(ld, "Error");
1812 	   return -1;
1813     }
1814 
1815     ret = ldap_count_entries(ld, msg);
1816 	if (ret == -1) {
1817 	   ldap_perror(ld, "Error");
1818 	   return -1;
1819     }
1820 
1821 	di = ldap_get_values(ld, msg, "di");
1822 	if ((di == NULL) || (di[0] == NULL)) {
1823 	   if (di)
1824 	      ldap_value_free(di);
1825 
1826 	   ldap_msgfree(res);
1827 	   return valias_delete(alias, domain);
1828     }
1829 
1830 	ldap_value_free(di);
1831 	ldap_msgfree(res);
1832     return(0);
1833 }
1834 
1835 
1836 /************************************************************************/
valias_delete(char * alias,char * domain)1837 int valias_delete( char *alias, char *domain)
1838 {
1839  int err, ret = 0;
1840  char ud[512] = { 0 }, dn[512] = { 0 };
1841 
1842     if ( (err=ldap_connect()) != 0 ) return(err);
1843 
1844 #ifdef ONCHANGE_SCRIPT
1845     if( allow_onchange ) {
1846        /* tell other programs that data has changed */
1847        snprintf ( onchange_buf, MAX_BUFF, "%s@%s", alias, domain );
1848        call_onchange ( "valias_delete" );
1849        }
1850 #endif
1851 
1852 	memset(ud, 0, sizeof(ud));
1853 	snprintf(ud, sizeof(ud), "%s@%s", alias, domain);
1854 
1855 	memset(dn, 0, sizeof(dn));
1856 	snprintf(dn, sizeof(dn), "aa=%s,ou=valias,%s", ud, VLDAP_BASEDN);
1857 
1858     ret = ldap_delete_s(ld, dn);
1859 	if (ret != LDAP_SUCCESS) {
1860         ldap_perror(ld,"Error");
1861         return -1;
1862     }
1863 
1864     return(0);
1865 }
1866 
1867 
1868 /************************************************************************/
valias_delete_domain(char * domain)1869 int valias_delete_domain( char *domain)
1870 {
1871  int err, ret;
1872  char filter[512] = { 0 }, dn[512] = { 0 };
1873  LDAPMessage *res = NULL, *msg = NULL;
1874  char **aa = NULL, *fields[] = { "aa",  NULL }, *p = NULL;
1875 
1876    if (ld == NULL) {
1877 	  err = ldap_connect();
1878 	  if (err)
1879 		 return 0;
1880    }
1881 
1882    memset(filter, 0, sizeof(filter));
1883    snprintf(filter, sizeof(filter), "aa=*@%s", domain);
1884 
1885    memset(dn, 0, sizeof(dn));
1886    snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
1887 
1888     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
1889                         filter, fields, 0, &res);
1890 
1891     if (ret != LDAP_SUCCESS ) {
1892         ldap_perror(ld,"Error");
1893         return 0;
1894     }
1895 
1896     msg = ldap_first_entry(ld, res);
1897     if (msg == NULL) {
1898 		 ldap_msgfree(res);
1899         return 0;
1900     }
1901 
1902     ret = ldap_count_entries(ld, msg);
1903     if (ret == -1 ) {
1904         ldap_perror(ld,"Error");
1905 		 ldap_msgfree(res);
1906         return 0;
1907     }
1908 
1909 	while(msg) {
1910 	   aa = ldap_get_values(ld, msg, "aa");
1911 	   if (aa == NULL) {
1912 		  fprintf(stderr, "vldap: warning: no address entry\n");
1913 	      msg = ldap_next_entry(ld, msg);
1914 		  continue;
1915 	   }
1916 
1917 	   for (p = *aa; *p; p++) {
1918 		  if (*p == '@') {
1919 			 *p = '\0';
1920 			 break;
1921 		  }
1922 	   }
1923 
1924 	   ret = valias_delete(*aa, domain);
1925 	   if (ret == -1)
1926 		  fprintf(stderr, "vldap: valias_delete_domain: valias_delete(%s@%s) failed\n", *aa, domain);
1927 
1928 	   ldap_value_free(aa);
1929 	   msg = ldap_next_entry(ld, msg);
1930     }
1931 
1932     return(0);
1933 }
1934 
1935 /************************************************************************/
valias_select_all(char * alias,char * domain)1936 char *valias_select_all( char *alias, char *domain )
1937 {
1938  int err, len, ret, i = 0;
1939  char filter[512] = { 0 }, dn[512] = { 0 };
1940  struct linklist *temp_entry = NULL;
1941  LDAPMessage *res = NULL, *msg = NULL;
1942  char **aa = NULL, **di = NULL, *fields[] = { "aa", "di", NULL }, *p = NULL;
1943 
1944    if (ld == NULL) {
1945 	  err = ldap_connect();
1946 	  if (err)
1947 		 return NULL;
1948    }
1949 
1950    memset(filter, 0, sizeof(filter));
1951    snprintf(filter, sizeof(filter), "aa=%s@%s", strcasecmp(alias, domain) ? alias : "*", domain);
1952 
1953    memset(dn, 0, sizeof(dn));
1954    snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
1955 
1956     while (valias_current != NULL)
1957         valias_current = linklist_del (valias_current);
1958 
1959     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
1960                         filter, fields, 0, &res);
1961     if (ret != LDAP_SUCCESS ) {
1962         ldap_perror(ld,"Error");
1963         return NULL;
1964     }
1965 
1966             if ( ldap_sort_entries( ld, &res, "aa", &strcasecmp ) != 0)  {
1967                 ldap_perror(ld,"Error");
1968                 return NULL;
1969             }
1970 
1971     msg = ldap_first_entry(ld, res);
1972     if (msg == NULL) {
1973 	    ldap_msgfree(res);
1974         return NULL;
1975     }
1976 
1977     ret = ldap_count_entries(ld, msg);
1978     if (ret == -1 ) {
1979 	    ldap_msgfree(res);
1980         ldap_perror(ld,"Error");
1981         return NULL;
1982     }
1983 
1984 	while(msg) {
1985 	   aa = ldap_get_values(ld, msg, "aa");
1986 	   if (aa == NULL) {
1987 		  fprintf(stderr, "vldap: warning: no address entry\n");
1988 		  msg = ldap_next_entry(ld, msg);
1989 		  continue;
1990 	   }
1991 
1992 	   di = ldap_get_values(ld, msg, "di");
1993 	   if (di == NULL) {
1994 		  fprintf(stderr, "vldap: warning: no delivery entries for '%s'\n", *aa);
1995 		  ldap_value_free(aa);
1996 	      msg = ldap_next_entry(ld, msg);
1997 		  continue;
1998 	   }
1999 
2000 	   for (p = *aa; *p; p++) {
2001 		  if (*p == '@') {
2002 			 *p = '\0';
2003 			 break;
2004 		  }
2005 	   }
2006 
2007 	   for (i = 0; di[i]; i++) {
2008 		   temp_entry = linklist_add(temp_entry, di[i], *aa);
2009 		   if (valias_current == NULL)
2010 		      valias_current = temp_entry;
2011 	   }
2012 
2013 	   ldap_value_free(aa);
2014 	   ldap_value_free(di);
2015 	   msg = ldap_next_entry(ld, msg);
2016     }
2017 
2018     if (valias_current == NULL) return NULL; /* no results */
2019     else {
2020 	    ldap_msgfree(res);
2021         strcpy (alias, valias_current->d2);
2022         return(valias_current->data);
2023     }
2024 }
2025 
2026 
2027 /************************************************************************/
valias_select_all_next(char * alias)2028 char *valias_select_all_next(char *alias)
2029 {
2030     if (valias_current == NULL) return NULL;
2031     valias_current = linklist_del (valias_current);
2032 
2033     if (valias_current == NULL) return NULL; /* no results */
2034     else {
2035         strcpy (alias, valias_current->d2);
2036         return(valias_current->data);
2037     }
2038 }
2039 
2040 /************************************************************************
2041  *
2042  *  valias_select_names
2043  */
2044 
valias_select_names(char * alias,char * domain)2045 char *valias_select_names( char *alias, char *domain )
2046 {
2047  int err, ret;
2048  char filter[512] = { 0 }, dn[512] = { 0 };
2049  struct linklist *temp_entry = NULL;
2050  LDAPMessage *res = NULL, *msg = NULL;
2051  char **aa = NULL,  *fields[] = { "aa",  NULL }, *p = NULL;
2052 
2053    if (ld == NULL) {
2054 	  err = ldap_connect();
2055 	  if (err)
2056 		 return NULL;
2057    }
2058 
2059    /*
2060 	  Passed via alias
2061    */
2062 
2063    domain = alias;
2064 
2065    memset(filter, 0, sizeof(filter));
2066    snprintf(filter, sizeof(filter), "aa=*@%s", domain);
2067 
2068    memset(dn, 0, sizeof(dn));
2069    snprintf(dn, sizeof(dn), "ou=valias,%s", VLDAP_BASEDN);
2070 
2071     while (valias_current != NULL)
2072         valias_current = linklist_del (valias_current);
2073 
2074     ret = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE,
2075                         filter, fields, 0, &res);
2076     if (ret != LDAP_SUCCESS ) {
2077         ldap_perror(ld,"Error");
2078         return NULL;
2079     }
2080 
2081             if ( ldap_sort_entries( ld, &res, "aa", &strcasecmp ) != 0)  {
2082                 ldap_perror(ld,"Error");
2083 				ldap_msgfree(res);
2084                 return NULL;
2085             }
2086 
2087     msg = ldap_first_entry(ld, res);
2088     if (msg == NULL) {
2089 		 ldap_msgfree(res);
2090         return NULL;
2091     }
2092 
2093     ret = ldap_count_entries(ld, msg);
2094     if (ret == -1 ) {
2095         ldap_perror(ld,"Error");
2096 		 ldap_msgfree(res);
2097         return NULL;
2098     }
2099 
2100 	while(msg) {
2101 	   aa = ldap_get_values(ld, msg, "aa");
2102 	   if (aa == NULL) {
2103 		  fprintf(stderr, "vldap: warning: no address entry\n");
2104 	      msg = ldap_next_entry(ld, msg);
2105 		  continue;
2106 	   }
2107 
2108 	   for (p = *aa; *p; p++) {
2109 		  if (*p == '@') {
2110 			 *p = '\0';
2111 			 break;
2112 		  }
2113 	   }
2114 
2115 	   temp_entry = linklist_add(temp_entry, *aa, *aa);
2116 	   if (valias_current == NULL)
2117 		  valias_current = temp_entry;
2118 
2119 	   ldap_value_free(aa);
2120 	   msg = ldap_next_entry(ld, msg);
2121     }
2122 
2123     if (valias_current == NULL) return NULL; /* no results */
2124     else {
2125         strcpy (alias, valias_current->d2);
2126 		 ldap_msgfree(res);
2127         return(valias_current->data);
2128     }
2129 }
2130 
2131 /************************************************************************
2132  *
2133  *  valias_select_names_next
2134  */
2135 
valias_select_names_next(char * alias)2136 char *valias_select_names_next(char *alias)
2137 {
2138     if (valias_current == NULL) return NULL;
2139     valias_current = linklist_del (valias_current);
2140 
2141     if (valias_current == NULL) return NULL; /* no results */
2142     else {
2143         strcpy (alias, valias_current->d2);
2144         return(valias_current->data);
2145     }
2146 }
2147 
2148 
2149 /************************************************************************
2150  *
2151  *  valias_select_names_end
2152  */
2153 
valias_select_names_end()2154 void valias_select_names_end() {
2155 
2156 //  not needed by ldap
2157 
2158 }
2159 
2160 #endif
2161