#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
#include <ctype.h>
#include <netinfo/ni.h>
#include <libc.h>
static const ni_name NAME_USERS = "users";
static const ni_name NAME_PASSWD = "passwd";
static int
changeit(
void *ni,
ni_id *id,
char *login,
char *old_passwd,
char *new_passwd
)
{
ni_proplist pl;
ni_index i;
ni_index prop_index;
ni_property prop;
ni_status stat;
ni_setabort(ni, TRUE);
ni_needwrite(ni, TRUE);
ni_setuser(ni, login);
ni_setpassword(ni, old_passwd);
if (ni_read(ni, id, &pl) != NI_OK) {
return (0);
}
prop_index = NI_INDEX_NULL;
for (i = 0; i < pl.nipl_len; i++) {
if (ni_name_match(pl.nipl_val[i].nip_name, NAME_PASSWD)) {
prop_index = i;
break;
}
}
if (prop_index == NI_INDEX_NULL) {
prop.nip_name = NAME_PASSWD;
prop.nip_val.ninl_len = 1;
prop.nip_val.ninl_val = &new_passwd;
stat = ni_createprop(ni, id, prop, NI_INDEX_NULL);
} else {
if (pl.nipl_val[i].nip_val.ninl_len == 0) {
stat = ni_createname(ni, id, prop_index,
new_passwd, 0);
} else {
stat = ni_writename(ni, id, prop_index, 0,
new_passwd);
}
}
ni_proplist_free(&pl);
return (stat == NI_OK);
}
int
putpwpasswd(
char *login,
char *old_passwd,
char *new_passwd
)
{
char *dir;
void *ni;
void *newni;
ni_id id;
ni_status stat;
int changed;
stat = ni_open(NULL, ".", &ni);
if (stat != NI_OK) {
return (0);
}
dir = malloc(1 + strlen(NAME_USERS) + 1 + strlen(login) + 1);
sprintf(dir, "/%s/%s", NAME_USERS, login);
changed = 0;
for (;;) {
stat = ni_pathsearch(ni, &id, dir);
if (stat == NI_OK) {
changed = changeit(ni, &id, login, old_passwd,
new_passwd);
break;
}
stat = ni_open(ni, "..", &newni);
if (stat != NI_OK) {
break;
}
ni_free(ni);
ni = newni;
}
free(dir);
ni_free(ni);
return (changed);
}