1 /* Copyright 1988, 1996 by the Massachusetts Institute of Technology.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 *
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 *
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26 * OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* This file is part of the Hesiod library. It implements
30 * hesiod_getpwnam and hesiod_getpwuid, for retrieving passwd
31 * information about a user.
32 */
33
34 static const char rcsid[] = "$Id: hespwnam.c,v 1.16 2002-04-03 21:40:55 ghudson Exp $";
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <pwd.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include "hesiod.h"
43 #include "config.h"
44
45 extern char **hesiod__uidresolve(void *context, const char *uidstr);
46
47 static struct passwd *getpwcommon(void *context, const char *arg, int which);
48 static char *next_field(char *ptr);
49
hesiod_getpwnam(void * context,const char * name)50 struct passwd *hesiod_getpwnam(void *context, const char *name)
51 {
52 return getpwcommon(context, name, 0);
53 }
54
hesiod_getpwuid(void * context,uid_t uid)55 struct passwd *hesiod_getpwuid(void *context, uid_t uid)
56 {
57 char uidstr[16];
58
59 sprintf(uidstr, "%u", (unsigned int)uid);
60 return getpwcommon(context, uidstr, 1);
61 }
62
hesiod_free_passwd(void * context,struct passwd * pw)63 void hesiod_free_passwd(void *context, struct passwd *pw)
64 {
65 free(pw->pw_name);
66 free(pw);
67 }
68
getpwcommon(void * context,const char * arg,int which)69 static struct passwd *getpwcommon(void *context, const char *arg, int which)
70 {
71 char *p, **list;
72 struct passwd *pw;
73
74 /* Get the response and copy the first entry into a buffer. */
75 list = hesiod_resolve(context, arg, which ? "uid" : "passwd");
76 if (!list)
77 return NULL;
78 p = malloc(strlen(*list) + 1);
79 if (!p)
80 {
81 hesiod_free_list(context, list);
82 errno = ENOMEM;
83 return NULL;
84 }
85 strcpy(p, *list);
86 hesiod_free_list(context, list);
87
88 /* Allocate memory for the result. */
89 pw = (struct passwd *) malloc(sizeof(struct passwd));
90 if (!pw)
91 {
92 free(p);
93 errno = ENOMEM;
94 return NULL;
95 }
96
97 /* Split up buf into fields. */
98 pw->pw_name = p;
99 p = next_field(p);
100 pw->pw_passwd = p;
101 p = next_field(p);
102 pw->pw_uid = atoi(p);
103 p = next_field(p);
104 pw->pw_gid = atoi(p);
105 p = next_field(p);
106 pw->pw_gecos = p;
107 p = next_field(p);
108 pw->pw_dir = p;
109 p = next_field(p);
110 pw->pw_shell = p;
111 while (*p && *p != '\n')
112 p++;
113 *p = 0;
114
115 #ifdef HAVE_PW_QUOTA
116 pw->pw_quota = 0;
117 #endif
118 #ifdef HAVE_PW_COMMENT
119 pw->pw_comment = "";
120 #endif
121 #ifdef HAVE_PW_CLASS
122 pw->pw_class = "";
123 #endif
124 #ifdef HAVE_PW_CHANGE
125 pw->pw_change = 0;
126 #endif
127 #ifdef HAVE_PW_EXPIRE
128 pw->pw_expire = 0;
129 #endif
130
131 return pw;
132 }
133
134 /* Null-terminate the current colon-separated field in the passwd entry and
135 * return a pointer to the beginning of the next one.
136 */
next_field(char * ptr)137 static char *next_field(char *ptr)
138 {
139 while (*ptr && *ptr != '\n' && *ptr != ':')
140 ptr++;
141 if (*ptr)
142 *ptr++ = '\0';
143 return ptr;
144 }
145