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"
25 #include "libhmac/hmac.h"
28 static const char rcsid
[]="$Id: authuserdbpwd.c,v 1.8 2006/10/28 19:22:52 mrsam Exp $";
31 static int bad(const char *q
)
36 if ((int)(unsigned char)*p
< ' ' || *p
== '|' || *p
== '='
37 || *p
== '\'' || *p
== '"')
45 static char *hmacpw(const char *pw
, const char *hash
)
49 for (i
=0; hmac_list
[i
] &&
50 strcmp(hmac_list
[i
]->hh_name
, hash
); i
++)
54 struct hmac_hashinfo
*hmac
=hmac_list
[i
];
55 unsigned char *p
=malloc(hmac
->hh_L
*2);
56 char *q
=malloc(hmac
->hh_L
*4+1);
65 hmac_hashkey(hmac
, pw
, strlen(pw
), p
, p
+hmac
->hh_L
);
66 for (i
=0; i
<hmac
->hh_L
*2; i
++)
67 sprintf(q
+i
*2, "%02x", (int)p
[i
]);
75 static int dochangepwd1(const char *, const char *, const char *, const char *,
78 static int try_auth_userdb_passwd(const char *hmac_flag
,
82 const char *npwd_buf
);
83 static int makeuserdb();
85 int auth_userdb_passwd(const char *service
,
93 if (bad(uid
) || strchr(uid
, '/'))
96 DPRINTF("userdb: %s is not a valid userid.\n",
106 DPRINTF("userdb: Invalid service or password string for %s.\n",
111 rc
=try_auth_userdb_passwd(NULL
, service
, uid
, opwd_buf
, npwd_buf
);
122 for (i
=0; hmac_list
[i
]; i
++)
124 const char *n
=hmac_list
[i
]->hh_name
;
126 char *hmacservice
=malloc(strlen(service
)+strlen(n
)
129 if (hmacservice
== NULL
)
132 strcat(strcat(strcpy(hmacservice
, service
),
135 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
147 strcat(strcpy(hmacservice
, "hmac-"), n
);
149 rc2
=try_auth_userdb_passwd(n
, hmacservice
, uid
,
168 DPRINTF("makeuserdb: error: %s", strerror(errno
));
172 DPRINTF("authuserdb: return code %d", rc
);
176 static int try_auth_userdb_passwd(const char *hmac_flag
,
179 const char *opwd_buf
,
180 const char *npwd_buf
)
190 DPRINTF("Trying to change password for %s",
193 DPWPRINTF("Old password=%s, new password=%s",
196 opwd
=hmacpw(opwd_buf
, hmac_flag
);
200 npwd
=hmacpw(npwd_buf
, hmac_flag
);
211 DPRINTF("Trying to change system password for %s",
214 DPWPRINTF("Old password=%s, new password=%s",
217 opwd
=strdup(opwd_buf
);
223 npwd
=userdb_mkmd5pw(npwd_buf
);
224 if (!npwd
|| !(npwd
=strdup(npwd
)))
233 rc
=dochangepwd1(service
, uid
, opwd
, npwd
, hmac_flag
);
240 static int dochangepwd2(const char *service
, const char *uid
,
242 const struct userdbs
*udb
, const char *npwd
);
244 static int dochangepwd1(const char *service
, const char *uid
,
245 const char *opwd
, const char *npwd
,
246 const char *hmac_flag
)
257 udbs
=userdbshadow(USERDB
"shadow.dat", uid
);
265 if ((services
=malloc(strlen(service
)+sizeof("pw"))) == 0)
273 strcat(strcpy(services
, service
), "pw");
275 DPRINTF("Checking for password called \"%s\"", services
);
277 passwords
=userdb_gets(udbs
, services
);
280 if (passwords
== 0 && hmac_flag
== 0)
282 DPRINTF("Not found, checking for \"systempw\"");
283 passwords
=userdb_gets(udbs
, "systempw");
287 if (!passwords
|| (hmac_flag
? strcmp(opwd
, passwords
):
288 authcheckpassword(opwd
, passwords
)))
292 DPRINTF("Password not found.");
296 DPRINTF("Password didn't match.");
308 userdb_init(USERDB
".dat");
309 if ( (u
=userdb(uid
)) == 0 ||
310 (udb
=userdb_creates(u
)) == 0)
318 rc
=dochangepwd2(service
, uid
, u
, udb
, npwd
);
325 static int dochangepwd2(const char *services
, const char *uid
,
327 const struct userdbs
*udb
, const char *npwd
)
333 argv
[0]=SBINDIR
"/userdb";
334 argv
[1]=malloc(strlen(udb
->udb_source
? udb
->udb_source
:"")
342 strcpy(argv
[1],udb
->udb_source
? udb
->udb_source
:"");
346 argv
[3]=malloc(strlen(services
)+strlen(npwd
)+10);
354 sprintf(argv
[3], "%spw=%s", services
, npwd
);
355 signal(SIGCHLD
, SIG_DFL
);
358 DPRINTF("Executing %s %s %s %s%s",
362 courier_authdebug_login_level
>= 2 ? argv
[3]:services
,
363 courier_authdebug_login_level
>= 2 ? "":"pw=******");
377 execv(argv
[0], argv
);
385 while ((p2
=wait(&waitstat
)) != p
)
387 if (p2
< 0 && errno
== ECHILD
)
395 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))
397 DPRINTF("Command failed: with exit code %d",
398 (int)WEXITSTATUS(waitstat
));
402 DPRINTF("Command succeeded: with exit code %d",
403 (int)WEXITSTATUS(waitstat
));
407 static int makeuserdb()
413 DPRINTF("Executing makeuserdb");
424 argv
[0]= SBINDIR
"/makeuserdb";
427 execv(argv
[0], argv
);
432 while ((p2
=wait(&waitstat
)) != p
)
434 if (p2
< 0 && errno
== ECHILD
)
441 if (!WIFEXITED(waitstat
) || WEXITSTATUS(waitstat
))