2 ** Copyright 2001-2005 Double Precision, Inc. See COPYING for
3 ** distribution information.
7 #include "courier_auth_config.h"
18 #include "userdb/userdb.h"
20 #include "courierauthstaticlist.h"
23 #include "courierauthdebug.h"
24 #include "libhmac/hmac.h"
28 static int bad(const char *q
)
33 if ((int)(unsigned char)*p
< ' ' || *p
== '|' || *p
== '='
34 || *p
== '\'' || *p
== '"')
40 static char *hmacpw(const char *pw
, const char *hash
)
44 for (i
=0; hmac_list
[i
] &&
45 strcmp(hmac_list
[i
]->hh_name
, hash
); i
++)
49 struct hmac_hashinfo
*hmac
=hmac_list
[i
];
50 unsigned char *p
=malloc(hmac
->hh_L
*2);
51 char *q
=malloc(hmac
->hh_L
*4+1);
60 hmac_hashkey(hmac
, pw
, strlen(pw
), p
, p
+hmac
->hh_L
);
61 for (i
=0; i
<hmac
->hh_L
*2; i
++)
62 sprintf(q
+i
*2, "%02x", (int)p
[i
]);
69 static int dochangepwd1(const char *, const char *, const char *, const char *,
72 static int try_auth_userdb_passwd(const char *hmac_flag
,
76 const char *npwd_buf
);
77 static int makeuserdb();
79 int auth_userdb_passwd(const char *service
,
87 if (bad(uid
) || strchr(uid
, '/'))
90 DPRINTF("userdb: %s is not a valid userid.\n",
100 DPRINTF("userdb: Invalid service or password string for %s.\n",
105 rc
=try_auth_userdb_passwd(NULL
, service
, uid
, opwd_buf
, npwd_buf
);
114 for (i
=0; hmac_list
[i
]; i
++)
116 const char *n
=hmac_list
[i
]->hh_name
;
118 char *hmacservice
=malloc(strlen(service
)+strlen(n
)
121 if (hmacservice
== NULL
)
124 strcat(strcat(strcpy(hmacservice
, service
),
127 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
139 strcat(strcpy(hmacservice
, "hmac-"), n
);
141 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
159 DPRINTF("makeuserdb: error: %s", strerror(errno
));
163 DPRINTF("authuserdb: return code %d", rc
);
167 static int try_auth_userdb_passwd(const char *hmac_flag
,
170 const char *opwd_buf
,
171 const char *npwd_buf
)
179 DPRINTF("Trying to change password for %s",
182 DPWPRINTF("Old password=%s, new password=%s",
185 opwd
=hmacpw(opwd_buf
, hmac_flag
);
189 npwd
=hmacpw(npwd_buf
, hmac_flag
);
199 DPRINTF("Trying to change system password for %s",
202 DPWPRINTF("Old password=%s, new password=%s",
205 opwd
=strdup(opwd_buf
);
211 npwd
=userdb_mkmd5pw(npwd_buf
);
212 if (!npwd
|| !(npwd
=strdup(npwd
)))
221 rc
=dochangepwd1(service
, uid
, opwd
, npwd
, hmac_flag
);
228 static int dochangepwd2(const char *service
, const char *uid
,
230 const struct userdbs
*udb
, const char *npwd
);
232 static int dochangepwd1(const char *service
, const char *uid
,
233 const char *opwd
, const char *npwd
,
234 const char *hmac_flag
)
245 udbs
=userdbshadow(USERDB
"shadow.dat", uid
);
253 if ((services
=malloc(strlen(service
)+sizeof("pw"))) == 0)
261 strcat(strcpy(services
, service
), "pw");
263 DPRINTF("Checking for password called \"%s\"", services
);
265 passwords
=userdb_gets(udbs
, services
);
268 if (passwords
== 0 && hmac_flag
== 0)
270 DPRINTF("Not found, checking for \"systempw\"");
271 passwords
=userdb_gets(udbs
, "systempw");
275 if (!passwords
|| (hmac_flag
? strcmp(opwd
, passwords
):
276 authcheckpassword(opwd
, passwords
)))
280 DPRINTF("Password not found.");
284 DPRINTF("Password didn't match.");
296 userdb_init(USERDB
".dat");
297 if ( (u
=userdb(uid
)) == 0 ||
298 (udb
=userdb_creates(u
)) == 0)
306 rc
=dochangepwd2(service
, uid
, u
, udb
, npwd
);
313 static int dochangepwd2(const char *services
, const char *uid
,
315 const struct userdbs
*udb
, const char *npwd
)
321 argv
[0]=SBINDIR
"/userdb";
322 argv
[1]=malloc(strlen(udb
->udb_source
? udb
->udb_source
:"")
330 strcpy(argv
[1],udb
->udb_source
? udb
->udb_source
:"");
334 argv
[3]=malloc(strlen(services
)+strlen(npwd
)+10);
342 sprintf(argv
[3], "%spw=%s", services
, npwd
);
343 signal(SIGCHLD
, SIG_DFL
);
346 DPRINTF("Executing %s %s %s %s%s",
350 courier_authdebug_login_level
>= 2 ? argv
[3]:services
,
351 courier_authdebug_login_level
>= 2 ? "":"pw=******");
365 execv(argv
[0], argv
);
373 while ((p2
=wait(&waitstat
)) != p
)
375 if (p2
< 0 && errno
== ECHILD
)
383 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))
385 DPRINTF("Command failed: with exit code %d",
386 (int)WEXITSTATUS(waitstat
));
390 DPRINTF("Command succeeded: with exit code %d",
391 (int)WEXITSTATUS(waitstat
));
395 static int makeuserdb()
401 DPRINTF("Executing makeuserdb");
412 argv
[0]= SBINDIR
"/makeuserdb";
415 execv(argv
[0], argv
);
420 while ((p2
=wait(&waitstat
)) != p
)
422 if (p2
< 0 && errno
== ECHILD
)
429 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))