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