Libinfo-78.tar.gz
[apple/libinfo.git] / util.subproj / putpwpasswd.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * putpwpasswd()
26 * Copyright (C) 1989 by NeXT, Inc.
27 *
28 * Changes a user's password entry. Works only for NetInfo.
29 *
30 * NOTE: This is not done in lookupd because we need to know
31 * the identity of the user and there is currently no way to
32 * get that information through a Mach message. Privileged users
33 * get privileged sockets and do not need to supply a old password
34 * if they are changing their password on the master server for their
35 * account entry. Unprivileged users get unprivileged sockets and must
36 * supply the old password.
37 */
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <pwd.h>
41 #include <ctype.h>
42 #include <netinfo/ni.h>
43 #include <libc.h>
44
45 static const ni_name NAME_USERS = "users";
46 static const ni_name NAME_PASSWD = "passwd";
47
48 static int
49 changeit(
50 void *ni,
51 ni_id *id,
52 char *login,
53 char *old_passwd,
54 char *new_passwd
55 )
56 {
57 ni_proplist pl;
58 ni_index i;
59 ni_index prop_index;
60 ni_property prop;
61 ni_status stat;
62
63 ni_setabort(ni, TRUE);
64 ni_needwrite(ni, TRUE);
65 ni_setuser(ni, login);
66 ni_setpassword(ni, old_passwd);
67
68 if (ni_read(ni, id, &pl) != NI_OK) {
69 return (0);
70 }
71 prop_index = NI_INDEX_NULL;
72 for (i = 0; i < pl.nipl_len; i++) {
73 if (ni_name_match(pl.nipl_val[i].nip_name, NAME_PASSWD)) {
74 prop_index = i;
75 break;
76 }
77 }
78 if (prop_index == NI_INDEX_NULL) {
79 prop.nip_name = NAME_PASSWD;
80 prop.nip_val.ninl_len = 1;
81 prop.nip_val.ninl_val = &new_passwd;
82 stat = ni_createprop(ni, id, prop, NI_INDEX_NULL);
83 } else {
84 if (pl.nipl_val[i].nip_val.ninl_len == 0) {
85 stat = ni_createname(ni, id, prop_index,
86 new_passwd, 0);
87 } else {
88 stat = ni_writename(ni, id, prop_index, 0,
89 new_passwd);
90 }
91 }
92 ni_proplist_free(&pl);
93 return (stat == NI_OK);
94 }
95
96 int
97 putpwpasswd(
98 char *login,
99 char *old_passwd, /* cleartext */
100 char *new_passwd /* encrypted */
101 )
102 {
103 char *dir;
104 void *ni;
105 void *newni;
106 ni_id id;
107 ni_status stat;
108 int changed;
109
110 stat = ni_open(NULL, ".", &ni);
111 if (stat != NI_OK) {
112 return (0);
113 }
114
115 dir = malloc(1 + strlen(NAME_USERS) + 1 + strlen(login) + 1);
116 sprintf(dir, "/%s/%s", NAME_USERS, login);
117
118 changed = 0;
119 for (;;) {
120 stat = ni_pathsearch(ni, &id, dir);
121 if (stat == NI_OK) {
122 changed = changeit(ni, &id, login, old_passwd,
123 new_passwd);
124 break;
125 }
126 stat = ni_open(ni, "..", &newni);
127 if (stat != NI_OK) {
128 break;
129 }
130 ni_free(ni);
131 ni = newni;
132 }
133 free(dir);
134 ni_free(ni);
135 return (changed);
136 }
137