1 #include "uniconfroot.h"
3 #include "wvtclstring.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
;
30 // FIXME: when do we plan to _free_ this?
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!
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
));
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
,
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());
85 *errnop
= errno
= ERANGE
;
86 return NSS_STATUS_TRYAGAIN
;
91 return NSS_STATUS_SUCCESS
;
96 static enum nss_status
grmatch(struct group
*gr
, int *errnop
,
97 char *buf
, size_t buflen
,
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());
107 gr
->gr_gid
= h
["/gidNumber"].getmeint();
108 gr
->gr_mem
= NULL
; // FIXME: ignore group expansion for now
112 *errnop
= errno
= ERANGE
;
113 return NSS_STATUS_TRYAGAIN
;
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
);
130 UniConf::RecursiveIter
i(users
);
131 for (i
.rewind(); i
.next(); )
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
);
154 UniConf::RecursiveIter
i(users
);
155 for (i
.rewind(); i
.next(); )
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
);
179 UniConf::RecursiveIter
i(users
);
180 for (i
.rewind(); i
.next(); )
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
);
203 UniConf::RecursiveIter
i(users
);
204 for (i
.rewind(); i
.next(); )
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
;