ypclnt_passwd.c (c552e298cb2544520538ae47f1054251b59038b6) ypclnt_passwd.c (c744e7522179b2cd69f9ba832b76cfb3c246735e)
1/*-
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.

--- 42 unchanged lines hidden (view full) ---

51#include <rpcsvc/yppasswd.h>
52
53#include "ypclnt.h"
54#include "yppasswd_private.h"
55
56static int yppasswd_remote(ypclnt_t *, const struct passwd *, const char *);
57static int yppasswd_local(ypclnt_t *, const struct passwd *, const char *);
58
1/*-
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.

--- 42 unchanged lines hidden (view full) ---

51#include <rpcsvc/yppasswd.h>
52
53#include "ypclnt.h"
54#include "yppasswd_private.h"
55
56static int yppasswd_remote(ypclnt_t *, const struct passwd *, const char *);
57static int yppasswd_local(ypclnt_t *, const struct passwd *, const char *);
58
59/*
60 * Determines the availability of rpc.yppasswdd. Returns -1 for not
61 * available (or unable to determine), 0 for available, 1 for available in
62 * master mode.
63 */
59int
64int
60ypclnt_passwd(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
65ypclnt_havepasswdd(ypclnt_t *ypclnt)
61{
62 struct addrinfo hints, *res;
63 int sd;
64
65 /* check that rpc.yppasswdd is running */
66 if (getrpcport(ypclnt->server, YPPASSWDPROG,
67 YPPASSWDPROC_UPDATE, IPPROTO_UDP) == 0) {
68 ypclnt_error(ypclnt, __func__, "no rpc.yppasswdd on server");
69 return (-1);
70 }
71
72 /* if we're not root, use remote method */
73 if (getuid() != 0)
66{
67 struct addrinfo hints, *res;
68 int sd;
69
70 /* check that rpc.yppasswdd is running */
71 if (getrpcport(ypclnt->server, YPPASSWDPROG,
72 YPPASSWDPROC_UPDATE, IPPROTO_UDP) == 0) {
73 ypclnt_error(ypclnt, __func__, "no rpc.yppasswdd on server");
74 return (-1);
75 }
76
77 /* if we're not root, use remote method */
78 if (getuid() != 0)
74 goto remote;
79 return (0);
75
76 /* try to determine if we are the server */
77 memset(&hints, 0, sizeof(hints));
78 hints.ai_family = AF_UNSPEC;
79 hints.ai_socktype = SOCK_STREAM;
80 hints.ai_protocol = 0;
81 if (getaddrinfo(ypclnt->server, NULL, &hints, &res) != 0)
80
81 /* try to determine if we are the server */
82 memset(&hints, 0, sizeof(hints));
83 hints.ai_family = AF_UNSPEC;
84 hints.ai_socktype = SOCK_STREAM;
85 hints.ai_protocol = 0;
86 if (getaddrinfo(ypclnt->server, NULL, &hints, &res) != 0)
82 goto remote;
87 return (0);
83 sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
84 if (sd == -1) {
85 freeaddrinfo(res);
88 sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
89 if (sd == -1) {
90 freeaddrinfo(res);
86 goto remote;
91 return (0);
87 }
88 if (bind(sd, res->ai_addr, res->ai_addrlen) == -1) {
89 close(sd);
90 freeaddrinfo(res);
92 }
93 if (bind(sd, res->ai_addr, res->ai_addrlen) == -1) {
94 close(sd);
95 freeaddrinfo(res);
91 goto remote;
96 return (0);
92 }
93 freeaddrinfo(res);
94 close(sd);
97 }
98 freeaddrinfo(res);
99 close(sd);
95 YPCLNT_DEBUG("using local update method");
96 return (yppasswd_local(ypclnt, pwd, passwd));
97 remote:
98 YPCLNT_DEBUG("using remote update method");
99 return (yppasswd_remote(ypclnt, pwd, passwd));
100 return (1);
100}
101
102/*
101}
102
103/*
104 * Updates the NIS user information for the specified user.
105 */
106int
107ypclnt_passwd(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
108{
109 switch (ypclnt_havepasswdd(ypclnt)) {
110 case 0:
111 YPCLNT_DEBUG("using remote update method");
112 return (yppasswd_remote(ypclnt, pwd, passwd));
113 case 1:
114 YPCLNT_DEBUG("using local update method");
115 return (yppasswd_local(ypclnt, pwd, passwd));
116 default:
117 YPCLNT_DEBUG("no rpc.yppasswdd");
118 return (-1);
119 }
120}
121
122/*
103 * yppasswd_remote and yppasswd_local are quite similar but still
104 * sufficiently different that merging them into one makes the code
105 * significantly less readable, IMHO, so we keep them separate.
106 */
107
108static int
109yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
110{

--- 11 unchanged lines hidden (view full) ---

122 yppwd.newpw.pw_expire = pwd->pw_expire;
123 yppwd.newpw.pw_fields = pwd->pw_fields;
124 if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
125 (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
126 (yppwd.newpw.pw_class = strdup(pwd->pw_class)) == NULL ||
127 (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
128 (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
129 (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
123 * yppasswd_remote and yppasswd_local are quite similar but still
124 * sufficiently different that merging them into one makes the code
125 * significantly less readable, IMHO, so we keep them separate.
126 */
127
128static int
129yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd)
130{

--- 11 unchanged lines hidden (view full) ---

142 yppwd.newpw.pw_expire = pwd->pw_expire;
143 yppwd.newpw.pw_fields = pwd->pw_fields;
144 if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
145 (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
146 (yppwd.newpw.pw_class = strdup(pwd->pw_class)) == NULL ||
147 (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
148 (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
149 (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
130 (yppwd.oldpass = strdup(passwd)) == NULL) {
150 (yppwd.oldpass = strdup(passwd ? passwd : "")) == NULL) {
131 ypclnt_error(ypclnt, __func__, strerror(errno));
132 ret = -1;
133 goto done;
134 }
135
136 /* connect to rpc.yppasswdd */
137 nc = getnetconfigent("unix");
138 clnt = clnt_tp_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, nc);

--- 66 unchanged lines hidden (view full) ---

205 memset(&yppwd, 0, sizeof yppwd);
206 yppwd.newpw.pw_uid = pwd->pw_uid;
207 yppwd.newpw.pw_gid = pwd->pw_gid;
208 if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
209 (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
210 (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
211 (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
212 (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
151 ypclnt_error(ypclnt, __func__, strerror(errno));
152 ret = -1;
153 goto done;
154 }
155
156 /* connect to rpc.yppasswdd */
157 nc = getnetconfigent("unix");
158 clnt = clnt_tp_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, nc);

--- 66 unchanged lines hidden (view full) ---

225 memset(&yppwd, 0, sizeof yppwd);
226 yppwd.newpw.pw_uid = pwd->pw_uid;
227 yppwd.newpw.pw_gid = pwd->pw_gid;
228 if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL ||
229 (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL ||
230 (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL ||
231 (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL ||
232 (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL ||
213 (yppwd.oldpass = strdup(passwd)) == NULL) {
233 (yppwd.oldpass = strdup(passwd ? passwd : "")) == NULL) {
214 ypclnt_error(ypclnt, __func__, strerror(errno));
215 ret = -1;
216 goto done;
217 }
218
219 /* connect to rpc.yppasswdd */
220 clnt = clnt_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, "udp");
221 if (clnt == NULL) {

--- 52 unchanged lines hidden ---
234 ypclnt_error(ypclnt, __func__, strerror(errno));
235 ret = -1;
236 goto done;
237 }
238
239 /* connect to rpc.yppasswdd */
240 clnt = clnt_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, "udp");
241 if (clnt == NULL) {

--- 52 unchanged lines hidden ---