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