Commit | Line | Data |
---|---|---|
7aa78013 AC |
1 | /* |
2 | Domtool (http://hcoop.sf.net/) | |
3 | Copyright (C) 2005-2007 Adam Chlipala | |
4 | ||
5 | This program is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU General Public License | |
7 | as published by the Free Software Foundation; either version 2 | |
8 | of the License, or (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 | ||
20 | // Setting a virtual mailbox's password if you know its current password | |
21 | ||
22 | #define _XOPEN_SOURCE | |
23 | #include <unistd.h> | |
f625c393 | 24 | #include <stdlib.h> |
7aa78013 AC |
25 | #include <stdio.h> |
26 | #include <ctype.h> | |
27 | #include <string.h> | |
28 | ||
29 | int validDomain(const char *dom) { | |
30 | for (; *dom; ++dom) | |
31 | if (*dom != '.' && *dom != '_' && *dom != '-' && !isalnum(*dom)) | |
32 | return 0; | |
33 | return 1; | |
34 | } | |
35 | ||
f625c393 | 36 | int main(int argc, char *argv[]) { |
7aa78013 AC |
37 | char *domain, addr[1024], cmd[1024], *crypted; |
38 | FILE *pw; | |
39 | int rc; | |
40 | ||
41 | if (argc != 4) { | |
42 | puts("Wrong number of arguments"); | |
43 | return 1; | |
44 | } | |
45 | ||
46 | if (strlen(argv[1]) >= 1024) { | |
47 | puts("Address too long"); | |
48 | return 1; | |
49 | } | |
50 | strcpy(addr, argv[1]); | |
51 | ||
52 | domain = strchr(addr, '@'); | |
53 | ||
54 | if (!domain) { | |
55 | puts("No @-sign found in address"); | |
56 | return 1; | |
57 | } | |
58 | *domain = 0; | |
59 | ++domain; | |
60 | ||
61 | if (!validDomain(addr)) { | |
62 | puts("Invalid local part"); | |
63 | return 1; | |
64 | } | |
65 | if (!validDomain(domain)) { | |
66 | puts("Invalid domain"); | |
67 | return 1; | |
68 | } | |
69 | ||
70 | sprintf(cmd, "/usr/sbin/userdb -show \"%s/%s\" | /bin/grep ^systempw=", domain, argv[1]); | |
71 | pw = popen(cmd, "r"); | |
72 | if (!pw) { | |
73 | puts("popen failure"); | |
74 | return 1; | |
75 | } | |
76 | ||
77 | if (fscanf(pw, "systempw=%1023[^\n]", cmd) != 1) { | |
78 | puts("Error parsing userdb output"); | |
79 | return 1; | |
80 | } | |
81 | ||
82 | pclose(pw); | |
83 | ||
84 | memcpy(addr, cmd, 2); | |
85 | addr[2] = 0; | |
86 | ||
87 | crypted = crypt(argv[2], addr); | |
88 | ||
89 | if (!crypted) { | |
90 | puts("Error encrypting"); | |
91 | return 1; | |
92 | } | |
93 | ||
94 | if (strlen(crypted) > 200){ | |
95 | puts("Encrypted password too long"); | |
96 | return 1; | |
97 | } | |
98 | ||
99 | if (strcmp(crypted, cmd)) { | |
100 | puts("Wrong password"); | |
101 | return 2; | |
102 | } | |
103 | ||
104 | sprintf(cmd, "/usr/sbin/userdbpw | /usr/sbin/userdb \"%s/%s\" set systempw", domain, argv[1]); | |
105 | pw = popen(cmd, "w"); | |
106 | ||
107 | if (!pw) { | |
108 | puts("Error running userdbpw"); | |
109 | return 1; | |
110 | } | |
111 | ||
112 | fputs(argv[3], pw); | |
113 | fputc('\n', pw); | |
114 | ||
115 | rc = pclose(pw); | |
116 | if (rc) { | |
117 | puts("userdbpw error"); | |
118 | return rc; | |
119 | } | |
120 | ||
37478a27 | 121 | return system("/usr/local/sbin/domtool-publish courier"); |
7aa78013 | 122 | } |