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 "authstaticlist.h"
23 #include "courierauthdebug.h"
24 #include "libhmac/hmac.h"
26 static const char rcsid
[]="$Id: authuserdbpwd.c,v 1.9 2008/07/10 02:43:55 mrsam Exp $";
29 static int bad(const char *q
)
34 if ((int)(unsigned char)*p
< ' ' || *p
== '|' || *p
== '='
35 || *p
== '\'' || *p
== '"')
41 static char *hmacpw(const char *pw
, const char *hash
)
45 for (i
=0; hmac_list
[i
] &&
46 strcmp(hmac_list
[i
]->hh_name
, hash
); i
++)
50 struct hmac_hashinfo
*hmac
=hmac_list
[i
];
51 unsigned char *p
=malloc(hmac
->hh_L
*2);
52 char *q
=malloc(hmac
->hh_L
*4+1);
61 hmac_hashkey(hmac
, pw
, strlen(pw
), p
, p
+hmac
->hh_L
);
62 for (i
=0; i
<hmac
->hh_L
*2; i
++)
63 sprintf(q
+i
*2, "%02x", (int)p
[i
]);
70 static int dochangepwd1(const char *, const char *, const char *, const char *,
73 static int try_auth_userdb_passwd(const char *hmac_flag
,
77 const char *npwd_buf
);
78 static int makeuserdb();
80 int auth_userdb_passwd(const char *service
,
88 if (bad(uid
) || strchr(uid
, '/'))
91 DPRINTF("userdb: %s is not a valid userid.\n",
101 DPRINTF("userdb: Invalid service or password string for %s.\n",
106 rc
=try_auth_userdb_passwd(NULL
, service
, uid
, opwd_buf
, npwd_buf
);
115 for (i
=0; hmac_list
[i
]; i
++)
117 const char *n
=hmac_list
[i
]->hh_name
;
119 char *hmacservice
=malloc(strlen(service
)+strlen(n
)
122 if (hmacservice
== NULL
)
125 strcat(strcat(strcpy(hmacservice
, service
),
128 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
140 strcat(strcpy(hmacservice
, "hmac-"), n
);
142 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
160 DPRINTF("makeuserdb: error: %s", strerror(errno
));
164 DPRINTF("authuserdb: return code %d", rc
);
168 static int try_auth_userdb_passwd(const char *hmac_flag
,
171 const char *opwd_buf
,
172 const char *npwd_buf
)
180 DPRINTF("Trying to change password for %s",
183 DPWPRINTF("Old password=%s, new password=%s",
186 opwd
=hmacpw(opwd_buf
, hmac_flag
);
190 npwd
=hmacpw(npwd_buf
, hmac_flag
);
200 DPRINTF("Trying to change system password for %s",
203 DPWPRINTF("Old password=%s, new password=%s",
206 opwd
=strdup(opwd_buf
);
212 npwd
=userdb_mkmd5pw(npwd_buf
);
213 if (!npwd
|| !(npwd
=strdup(npwd
)))
222 rc
=dochangepwd1(service
, uid
, opwd
, npwd
, hmac_flag
);
229 static int dochangepwd2(const char *service
, const char *uid
,
231 const struct userdbs
*udb
, const char *npwd
);
233 static int dochangepwd1(const char *service
, const char *uid
,
234 const char *opwd
, const char *npwd
,
235 const char *hmac_flag
)
246 udbs
=userdbshadow(USERDB
"shadow.dat", uid
);
254 if ((services
=malloc(strlen(service
)+sizeof("pw"))) == 0)
262 strcat(strcpy(services
, service
), "pw");
264 DPRINTF("Checking for password called \"%s\"", services
);
266 passwords
=userdb_gets(udbs
, services
);
269 if (passwords
== 0 && hmac_flag
== 0)
271 DPRINTF("Not found, checking for \"systempw\"");
272 passwords
=userdb_gets(udbs
, "systempw");
276 if (!passwords
|| (hmac_flag
? strcmp(opwd
, passwords
):
277 authcheckpassword(opwd
, passwords
)))
281 DPRINTF("Password not found.");
285 DPRINTF("Password didn't match.");
297 userdb_init(USERDB
".dat");
298 if ( (u
=userdb(uid
)) == 0 ||
299 (udb
=userdb_creates(u
)) == 0)
307 rc
=dochangepwd2(service
, uid
, u
, udb
, npwd
);
314 static int dochangepwd2(const char *services
, const char *uid
,
316 const struct userdbs
*udb
, const char *npwd
)
322 argv
[0]=SBINDIR
"/userdb";
323 argv
[1]=malloc(strlen(udb
->udb_source
? udb
->udb_source
:"")
331 strcpy(argv
[1],udb
->udb_source
? udb
->udb_source
:"");
335 argv
[3]=malloc(strlen(services
)+strlen(npwd
)+10);
343 sprintf(argv
[3], "%spw=%s", services
, npwd
);
344 signal(SIGCHLD
, SIG_DFL
);
347 DPRINTF("Executing %s %s %s %s%s",
351 courier_authdebug_login_level
>= 2 ? argv
[3]:services
,
352 courier_authdebug_login_level
>= 2 ? "":"pw=******");
366 execv(argv
[0], argv
);
374 while ((p2
=wait(&waitstat
)) != p
)
376 if (p2
< 0 && errno
== ECHILD
)
384 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))
386 DPRINTF("Command failed: with exit code %d",
387 (int)WEXITSTATUS(waitstat
));
391 DPRINTF("Command succeeded: with exit code %d",
392 (int)WEXITSTATUS(waitstat
));
396 static int makeuserdb()
402 DPRINTF("Executing makeuserdb");
413 argv
[0]= SBINDIR
"/makeuserdb";
416 execv(argv
[0], argv
);
421 while ((p2
=wait(&waitstat
)) != p
)
423 if (p2
< 0 && errno
== ECHILD
)
430 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))