Use addr, not p for inet_pton call.
[kopensolaris-gnu/glibc.git] / nis / nss_nis / nis-publickey.c
1 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <nss.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <syslog.h>
25 #include <libc-lock.h>
26 #include <rpc/rpc.h>
27 #include <rpcsvc/yp.h>
28 #include <rpcsvc/ypclnt.h>
29 #if defined (HAVE_SECURE_RPC)
30 #include <rpc/key_prot.h>
31 extern int xdecrypt (char *, char *);
32 #endif
33
34 #include "nss-nis.h"
35
36 /* If we haven't found the entry, we give a SUCCESS and an empty key back. */
37 enum nss_status
38 _nss_nis_getpublickey (const char *netname, char *pkey)
39 {
40   enum nss_status retval;
41   char *domain, *result;
42   int len;
43   
44   pkey[0] = 0;
45
46   if (netname == NULL)
47     {
48       __set_errno (EINVAL);
49       return NSS_STATUS_UNAVAIL;
50     }
51
52   domain = strchr (netname, '@');
53   if (!domain)
54     return NSS_STATUS_UNAVAIL;
55   domain++;
56
57   retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
58                                 strlen (netname), &result, &len));
59
60   if (retval != NSS_STATUS_SUCCESS)
61     {
62       if (retval == NSS_STATUS_TRYAGAIN)
63         __set_errno (EAGAIN);
64       return retval;
65     }
66
67   if (result != NULL)
68     {
69       char *p = strchr (result, ':');
70       if (p != NULL)
71         *p = 0;
72       strcpy (pkey, result);
73     }
74   return NSS_STATUS_SUCCESS;
75 }
76
77 enum nss_status
78 _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
79 {
80 #if defined (HAVE_SECURE_RPC)
81   enum nss_status retval;
82   char buf[1024];
83   char *domain, *result;
84   int len;
85
86   skey[0] = 0;
87
88   if (netname == NULL || passwd == NULL)
89     {
90       __set_errno (EINVAL);
91       return NSS_STATUS_UNAVAIL;
92     }
93
94   domain = strchr (netname, '@');
95   if (!domain)
96     return NSS_STATUS_UNAVAIL;
97   domain++;
98
99   retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
100                                 strlen (netname), &result, &len));
101
102   if (retval != NSS_STATUS_SUCCESS)
103     {
104       if (retval == NSS_STATUS_TRYAGAIN)
105         __set_errno (EAGAIN);
106       return retval;
107     }
108
109   if (result != NULL)
110     {
111       char *p = strchr (result, ':');
112       if (p == NULL)
113         return NSS_STATUS_SUCCESS;
114
115       p++;
116       strcpy (buf, p);
117       if (!xdecrypt (buf, passwd))
118         return NSS_STATUS_SUCCESS;
119
120       if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
121         return NSS_STATUS_SUCCESS;
122
123       buf[HEXKEYBYTES] = 0;
124       strcpy (skey, buf);
125     }
126 #else
127   skey[0] = 0;
128 #endif
129   return NSS_STATUS_SUCCESS;
130 }
131
132 /* Parse uid and group information from the passed string.
133    The format of the string passed is uid:gid,grp,grp, ...  */
134 static enum nss_status
135 parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
136                  gid_t *gidlist)
137 {
138   char *p;
139   int gidlen;
140
141   if (!s || !isdigit (*s))
142     {
143       syslog (LOG_ERR, "netname2user: expecting uid '%s'", s);
144       return NSS_STATUS_NOTFOUND;       /* XXX need a better error */
145     }
146
147   /* Fetch the uid */
148   *uidp = (atoi (s));
149
150   if (*uidp == 0)
151     {
152       syslog (LOG_ERR, "netname2user: should not have uid 0");
153       return NSS_STATUS_NOTFOUND;
154     }
155
156   /* Now get the group list */
157   p = strchr (s, ':');
158   if (!p)
159     {
160       syslog (LOG_ERR, "netname2user: missing group id list in '%s'", s);
161       return NSS_STATUS_NOTFOUND;
162     }
163   ++p;                          /* skip ':' */
164   if (!p || (!isdigit (*p)))
165     {
166       syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", p);
167       return NSS_STATUS_NOTFOUND;
168     }
169
170   *gidp = (atoi (p));
171
172   gidlen = 0;
173
174   while ((p = strchr (p, ',')) != NULL)
175     {
176       p++;
177       gidlist[gidlen++] = atoi (p);
178     }
179
180   *gidlenp = gidlen;
181
182   return NSS_STATUS_SUCCESS;
183 }
184
185
186 enum nss_status
187 _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
188                        gid_t *gidp, int *gidlenp, gid_t *gidlist)
189 {
190   char *domain;
191   int yperr;
192   char *lookup;
193   int len;
194
195   domain = strchr (netname, '@');
196   if (!domain)
197     return NSS_STATUS_UNAVAIL;
198
199   /* Point past the '@' character */
200   domain++;
201   lookup = NULL;
202   yperr = yp_match (domain, "netid.byname", netname, strlen (netname),
203                     &lookup, &len);
204   switch (yperr)
205     {
206     case YPERR_SUCCESS:
207       break;                    /* the successful case */
208     case YPERR_DOMAIN:
209     case YPERR_KEY:
210       return NSS_STATUS_NOTFOUND;
211     case YPERR_MAP:
212     default:
213       return NSS_STATUS_UNAVAIL;
214     }
215   if (lookup)
216     {
217       enum nss_status err;
218
219       lookup[len] = '\0';
220       err = parse_netid_str (lookup, uidp, gidp, gidlenp, gidlist);
221       free (lookup);
222       return err;
223     }
224   else
225     return NSS_STATUS_NOTFOUND;
226
227   return NSS_STATUS_SUCCESS;
228 }