HEAD: removed mrwise debug crud from uniclientgen.cc.
[wvapps.git] / nss / libnss_uniconf.cc
blob39b041e19ea0825ebba5dcbaf12839efd826bac1
1 #include "uniconfroot.h"
2 #include "wvlog.h"
3 #include "wvtclstring.h"
5 #include <stdio.h>
6 #include <nss.h>
7 #include <pwd.h>
8 #include <grp.h>
9 #include <sys/types.h>
10 #include <errno.h>
12 // the following are not implemented yet:
13 extern "C" enum nss_status _nss_uniconf_setpwent();
14 extern "C" enum nss_status _nss_uniconf_endpwent();
16 extern "C" enum nss_status _nss_uniconf_setgrent();
17 extern "C" enum nss_status _nss_uniconf_endgrent();
18 //extern "C" enum nss_status _nss_uniconf_getgrnam_r();
19 //extern "C" enum nss_status _nss_uniconf_getgrgid_r();
21 extern "C" enum nss_status _nss_uniconf_initgroups_dyn();
24 static WvLog log("nss-uniconf", WvLog::Debug5);
25 static UniConfRoot *cfgroot = NULL;
26 static UniConf cfg, users;
28 static void init()
30 // FIXME: when do we plan to _free_ this?
31 if (!cfgroot)
33 // the basic config comes from nss-uniconf.conf.
34 cfgroot = new UniConfRoot();
35 cfg = UniConf(*cfgroot);
37 cfg.mount("ini:nss-uniconf.conf");
39 // if an option isn't found in there, look in /etc/nss-uniconf.conf.
40 UniConf cfg2(cfg["EtcConfig"]);
41 cfg2.mount("ini:/etc/nss-uniconf.conf");
42 // cfg.setdefaults(cfg2); FIXME
44 // the /Users branch comes from ./users.ini for now; eventually it'll
45 // probably come from a user-defined spot (as specified in the config
46 // file). Note that the config file can override some user settings!
47 users = cfg["Users"];
48 users.mount("ini:users.ini");
53 static char *putmatch(WvBuf &out, WvStringParm s)
55 WvConstStringBuffer buf(s);
57 int startofs = out.used();
58 out.putstr(wvtcl_getword(buf));
59 out.putch(0);
61 return (char *)out.mutablepeek(startofs, out.used() - (unsigned)startofs);
65 static enum nss_status pwmatch(struct passwd *pw, int *errnop,
66 char *buf, size_t buflen,
67 const UniConf &h)
69 WvInPlaceBuf out(buf, 0, buflen);
71 // make sure things have default values
72 // h.setdefaults(cfg["Defaults/Users"]); FIXME
73 // h["gecos"].setdefaults(h["uid"]); FIXME
75 pw->pw_name = putmatch(out, h["/uid"].getme());
76 pw->pw_passwd = putmatch(out, "x");
77 pw->pw_uid = h["/uidNumber"].getmeint();
78 pw->pw_gid = h["/gidNumber"].getmeint();
79 pw->pw_gecos = putmatch(out, h["/gecos"].getme());
80 pw->pw_dir = putmatch(out, h["/homeDirectory"].getme());
81 pw->pw_shell = putmatch(out, h["/loginShell"].getme());
83 if (out.free() == 0)
85 *errnop = errno = ERANGE;
86 return NSS_STATUS_TRYAGAIN;
88 else
90 *errnop = errno = 0;
91 return NSS_STATUS_SUCCESS;
96 static enum nss_status grmatch(struct group *gr, int *errnop,
97 char *buf, size_t buflen,
98 const UniConf &h)
100 WvInPlaceBuf out(buf, 0, buflen);
102 // make sure things have default values
103 // h.setdefaults(cfg["Defaults/Groups"]); FIXME
105 gr->gr_name = putmatch(out, h["/uid"].getme());
106 gr->gr_passwd = "x";
107 gr->gr_gid = h["/gidNumber"].getmeint();
108 gr->gr_mem = NULL; // FIXME: ignore group expansion for now
110 if (out.free() == 0)
112 *errnop = errno = ERANGE;
113 return NSS_STATUS_TRYAGAIN;
115 else
117 *errnop = errno = 0;
118 return NSS_STATUS_SUCCESS;
123 extern "C" enum nss_status _nss_uniconf_getpwnam_r(
124 const char *user, struct passwd *pw,
125 char *buf, size_t buflen, int *errnop)
127 log("%s(%s) called.\n", __func__, user);
128 init();
130 UniConf::RecursiveIter i(users);
131 for (i.rewind(); i.next(); )
133 UniConf h(*i);
134 UniConf parent(h.parent());
135 if (h.key() == UniConfKey("/uidNumber") &&
136 parent["/uid"].getme() == WvString(user))
138 return pwmatch(pw, errnop, buf, buflen, parent);
142 *errnop = errno = ENOENT;
143 return NSS_STATUS_NOTFOUND;
147 extern "C" enum nss_status _nss_uniconf_getpwuid_r(
148 uid_t uid, struct passwd *pw,
149 char *buf, size_t buflen, int *errnop)
151 log("%s(%s) called.\n", __func__, uid);
152 init();
154 UniConf::RecursiveIter i(users);
155 for (i.rewind(); i.next(); )
157 UniConf h(*i);
158 UniConf parent(h.parent());
159 if (h.key() == UniConfKey("/uidNumber") &&
160 (uid_t)h.getmeint() == uid)
162 return pwmatch(pw, errnop, buf, buflen, parent);
166 *errnop = errno = ENOENT;
167 return NSS_STATUS_NOTFOUND;
172 extern "C" enum nss_status _nss_uniconf_getgrnam_r(
173 const char *user, struct group *gr,
174 char *buf, size_t buflen, int *errnop)
176 log("%s(%s) called.\n", __func__, user);
177 init();
179 UniConf::RecursiveIter i(users);
180 for (i.rewind(); i.next(); )
182 UniConf h(*i);
183 UniConf parent(h.parent());
184 if (h.key() == UniConfKey("/gidNumber") &&
185 parent["/cn"].getme() == WvString(user))
187 return grmatch(gr, errnop, buf, buflen, parent);
191 *errnop = errno = ENOENT;
192 return NSS_STATUS_NOTFOUND;
196 extern "C" enum nss_status _nss_uniconf_getgrgid_r(
197 gid_t gid, struct group *gr,
198 char *buf, size_t buflen, int *errnop)
200 log("%s(%s) called.\n", __func__, gid);
201 init();
203 UniConf::RecursiveIter i(users);
204 for (i.rewind(); i.next(); )
206 UniConf h(*i);
207 UniConf parent(h.parent());
208 if (h.key() == UniConfKey("/gidNumber") &&
209 (gid_t)h.getmeint() == gid)
211 return grmatch(gr, errnop, buf, buflen, parent);
215 *errnop = errno = ENOENT;
216 return NSS_STATUS_NOTFOUND;