/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights * Reserved. This file contains Original Code and/or Modifications of * Original Code as defined in and that are subject to the Apple Public * Source License Version 1.1 (the "License"). You may not use this file * except in compliance with the License. Please obtain a copy of the * License at http://www.apple.com/publicsource and read it before using * this file. * * The Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * putpwpasswd() * Copyright (C) 1989 by NeXT, Inc. * * Changes a user's password entry. Works only for NetInfo. * * NOTE: This is not done in lookupd because we need to know * the identity of the user and there is currently no way to * get that information through a Mach message. Privileged users * get privileged sockets and do not need to supply a old password * if they are changing their password on the master server for their * account entry. Unprivileged users get unprivileged sockets and must * supply the old password. */ #include #include #include #include #include #include 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, /* cleartext */ char *new_passwd /* encrypted */ ) { 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); }