36f66a0c |
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> |
24 | #include <stdio.h> |
25 | #include <ctype.h> |
26 | #include <string.h> |
27 | |
28 | int validDomain(const char *dom) { |
29 | for (; *dom; ++dom) |
30 | if (*dom != '.' && *dom != '_' && *dom != '-' && !isalnum(*dom)) |
31 | return 0; |
32 | return 1; |
33 | } |
34 | |
35 | main(int argc, char *argv[]) { |
36 | char *domain, addr[1024], cmd[1024], *crypted; |
37 | FILE *pw; |
38 | int rc; |
39 | |
40 | if (argc != 4) { |
41 | puts("Wrong number of arguments"); |
42 | return 1; |
43 | } |
44 | |
45 | if (strlen(argv[1]) >= 1024) { |
46 | puts("Address too long"); |
47 | return 1; |
48 | } |
49 | strcpy(addr, argv[1]); |
50 | |
51 | domain = strchr(addr, '@'); |
52 | |
53 | if (!domain) { |
54 | puts("No @-sign found in address"); |
55 | return 1; |
56 | } |
57 | *domain = 0; |
58 | ++domain; |
59 | |
60 | if (!validDomain(addr)) { |
61 | puts("Invalid local part"); |
62 | return 1; |
63 | } |
64 | if (!validDomain(domain)) { |
65 | puts("Invalid domain"); |
66 | return 1; |
67 | } |
68 | |
69 | sprintf(cmd, "/usr/sbin/userdb -show \"%s/%s\" | /bin/grep ^systempw=", domain, argv[1]); |
70 | pw = popen(cmd, "r"); |
71 | if (!pw) { |
72 | puts("popen failure"); |
73 | return 1; |
74 | } |
75 | |
76 | if (fscanf(pw, "systempw=%1023[^\n]", cmd) != 1) { |
77 | puts("Error parsing userdb output"); |
78 | return 1; |
79 | } |
80 | |
81 | pclose(pw); |
82 | |
83 | memcpy(addr, cmd, 2); |
84 | addr[2] = 0; |
85 | |
86 | crypted = crypt(argv[2], addr); |
87 | |
88 | if (!crypted) { |
89 | puts("Error encrypting"); |
90 | return 1; |
91 | } |
92 | |
93 | if (strlen(crypted) > 200){ |
94 | puts("Encrypted password too long"); |
95 | return 1; |
96 | } |
97 | |
98 | if (strcmp(crypted, cmd)) { |
99 | puts("Wrong password"); |
100 | return 2; |
101 | } |
102 | |
103 | sprintf(cmd, "/usr/sbin/userdbpw | /usr/sbin/userdb \"%s/%s\" set systempw", domain, argv[1]); |
104 | pw = popen(cmd, "w"); |
105 | |
106 | if (!pw) { |
107 | puts("Error running userdbpw"); |
108 | return 1; |
109 | } |
110 | |
111 | fputs(argv[3], pw); |
112 | fputc('\n', pw); |
113 | |
114 | rc = pclose(pw); |
115 | if (rc) { |
116 | puts("userdbpw error"); |
117 | return rc; |
118 | } |
119 | |
cf6d96ab |
120 | return system("/usr/local/bin/domtool-publish courier"); |
36f66a0c |
121 | } |