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