1/*
2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1990 Jan-Simon Pendry
4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 *    must display the following acknowledgment:
21 *      This product includes software developed by the University of
22 *      California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 *    may be used to endorse or promote products derived from this software
25 *    without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 *
40 * File: am-utils/amd/info_passwd.c
41 *
42 */
43
44/*
45 * Get info from password "file"
46 *
47 * This is experimental and probably doesn't do what you expect.
48 */
49
50#ifdef HAVE_CONFIG_H
51# include <config.h>
52#endif /* HAVE_CONFIG_H */
53#include <am_defs.h>
54#include <amd.h>
55
56#define	PASSWD_MAP	"/etc/passwd"
57
58/* forward declarations */
59int passwd_init(mnt_map *m, char *map, time_t *tp);
60int passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp);
61
62
63/*
64 * Nothing to probe - check the map name is PASSWD_MAP.
65 */
66int
67passwd_init(mnt_map *m, char *map, time_t *tp)
68{
69  *tp = 0;
70
71  /*
72   * Recognize the old format "PASSWD_MAP"
73   * Uses default return string
74   * "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}"
75   */
76  if (STREQ(map, PASSWD_MAP))
77    return 0;
78  /*
79   * Recognize the new format "PASSWD_MAP:pval-format"
80   */
81  if (!NSTREQ(map, PASSWD_MAP, sizeof(PASSWD_MAP) - 1))
82    return ENOENT;
83  if (map[sizeof(PASSWD_MAP)-1] != ':')
84    return ENOENT;
85
86  return 0;
87}
88
89
90/*
91 * Grab the entry via the getpwname routine
92 * Modify time is ignored by passwd - XXX
93 */
94int
95passwd_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
96{
97  char *dir = 0;
98  struct passwd *pw;
99
100  if (STREQ(key, "/defaults")) {
101    *pval = strdup("type:=nfs");
102    return 0;
103  }
104  pw = getpwnam(key);
105
106  if (pw) {
107    /*
108     * We chop the home directory up as follows:
109     * /anydir/dom1/dom2/dom3/user
110     *
111     * and return
112     * rfs:=/anydir/dom3;rhost:=dom3.dom2.dom1;sublink:=user
113     * and now have
114     * var0:=pw-prefix:=anydir
115     * var1:=pw-rhost:=dom3.dom2.dom1
116     * var2:=pw-user:=user
117     * var3:=pw-home:=/anydir/dom1/dom2/dom3/user
118     *
119     * This allows cross-domain entries in your passwd file.
120     * ... but forget about security!
121     */
122    char *user;
123    char *p, *q;
124    char val[MAXPATHLEN];
125    char rhost[MAXHOSTNAMELEN];
126    dir = strdup(pw->pw_dir);
127
128    /*
129     * Find user name.  If no / then Invalid...
130     */
131    user = strrchr(dir, '/');
132    if (!user)
133      goto enoent;
134    *user++ = '\0';
135
136    /*
137     * Find start of host "path".  If no / then Invalid...
138     */
139    p = strchr(dir + 1, '/');
140    if (!p)
141      goto enoent;
142    *p++ = '\0';
143
144    /*
145     * At this point, p is dom1/dom2/dom3
146     * Copy, backwards, into rhost replacing
147     * / with .
148     */
149    rhost[0] = '\0';
150    do {
151      q = strrchr(p, '/');
152      if (q) {
153	xstrlcat(rhost, q + 1, sizeof(rhost));
154	xstrlcat(rhost, ".", sizeof(rhost));
155	*q = '\0';
156      } else {
157	xstrlcat(rhost, p, sizeof(rhost));
158      }
159    } while (q);
160
161    /*
162     * Sanity check
163     */
164    if (*rhost == '\0' || *user == '\0' || *dir == '\0')
165      goto enoent;
166
167    /*
168     * Make up return string
169     */
170    q = strchr(rhost, '.');
171    if (q)
172      *q = '\0';
173    p = strchr(map, ':');
174    if (p)
175      p++;
176    else
177      p = "type:=nfs;rfs:=/${var0}/${var1};rhost:=${var1};sublink:=${var2};fs:=${autodir}${var3}";
178    xsnprintf(val, sizeof(val), "var0:=%s;var1:=%s;var2:=%s;var3:=%s;%s",
179	      dir+1, rhost, user, pw->pw_dir, p);
180    dlog("passwd_search: map=%s key=%s -> %s", map, key, val);
181    if (q)
182      *q = '.';
183    *pval = strdup(val);
184    return 0;
185  }
186
187enoent:
188  if (dir)
189    XFREE(dir);
190
191  return ENOENT;
192}
193