DEFINE_DATABASE (aliases)
#ifdef __OpenSolaris_kernel__
DEFINE_DATABASE (auth_attr)
-DEFINE_DATABASE (automount)
DEFINE_DATABASE (bootparams)
#endif
DEFINE_DATABASE (ethers)
_getprofnam _getprofattr _getusernam _getuserattr _getauuserent \
_getauusernam vfsent fdwalk closefrom ipsecalg gethostent sigsendset \
sigsend stack_getbounds thr_sighndlrinfo sun_compat mkdev nss_getent \
- nss_setent nss_endent nss_misc
+ nss_setent nss_endent nss_search nss_misc
sysdep_routines += sys_fdsync sys_brk sys_fcntl sys_utssys sys_lwp_private \
sys_uname sys_getloadavg sys_utimes sys_getpeerucred sys_ucred_get \
sys_privsys sys_putmsg sys_putpmsg sys_meminfo sys_pset_getloadavg \
endif
ifeq ($(subdir),nss)
-databases += auth_attr automount bootparams netmasks printers prof_attr project
+databases += auth_attr bootparams netmasks printers prof_attr project
endif
ifeq ($(subdir),nptl)
#define SETFUNC_NAME _setauthattr
#define GETFUNC_NAME _getauthattr
#define ENDFUNC_NAME _endauthattr
-#define DATABASE_NAME auth_attr
+#define DATABASE_NAME passwd
#define BUFLEN NSS_BUFLEN_PROFATTR
#include "../nss/getXXent_r.c"
#define LOOKUP_TYPE authstr_t
#define FUNCTION_NAME _getauthnam
-#define DATABASE_NAME auth_attr
+#define DATABASE_NAME passwd
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
#define BUFLEN NSS_BUFLEN_PROFATTR
#define SETFUNC_NAME _setauuser
#define GETFUNC_NAME _getauuserent
#define ENDFUNC_NAME _endauuser
-#define DATABASE_NAME audit_user
+#define DATABASE_NAME passwd
#define BUFLEN NSS_BUFLEN_AUDITUSER
#include "../nss/getXXent_r.c"
#define LOOKUP_TYPE au_user_str_t
#define FUNCTION_NAME _getauusernam
-#define DATABASE_NAME audit_user
+#define DATABASE_NAME passwd
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
#define BUFLEN NSS_BUFLEN_AUDITUSER
#define SETFUNC_NAME _setuserattr
#define GETFUNC_NAME _getuserattr
#define ENDFUNC_NAME _enduserattr
-#define DATABASE_NAME user_attr
+#define DATABASE_NAME passwd
#define BUFLEN NSS_BUFLEN_PROFATTR
#include "../nss/getXXent_r.c"
#define LOOKUP_TYPE userstr_t
#define FUNCTION_NAME _getusernam
-#define DATABASE_NAME user_attr
+#define DATABASE_NAME passwd
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
#define BUFLEN NSS_BUFLEN_PROFATTR
__libc_lock_lock (contextpp->lock);
struct nss_getent_context *ctx = contextpp->ctx;
- __nss_endent (ctx->endfuncname, ctx->dblookup, &ctx->nip, &ctx->startp,
+ __nss_endent (ctx->endfuncname, ctx->dblookupfunc, &ctx->nip, &ctx->startp,
&ctx->last_nip, 0);
/* Free context. */
// TODO: Store nssargs->str2ent in a global table and use it for parsing.
int res = __nss_getent_r (ctx->getfuncname, ctx->setfuncname,
- ctx->dblookup, &ctx->nip, &ctx->startp, &ctx->last_nip,
+ ctx->dblookupfunc, &ctx->nip, &ctx->startp, &ctx->last_nip,
&ctx->stayopen_tmp, 0, nssargs->buf.result, nssargs->buf.buffer,
nssargs->buf.buflen, &nssargs->returnval, &nssargs->h_errno);
#include <nss_sunP.h>
#include <string.h>
-int __nss_dbname_to_dbid (const char *dbname)
+int __nss_get_dbid (const char *dbname)
{
if (strcmp (dbname, "auth_attr") == 0)
return NSS_DBID_AUTH_ATTR;
- if (strcmp (dbname, "automount") == 0)
- return NSS_DBID_AUTOMOUNT;
if (strcmp (dbname, "bootparams") == 0)
return NSS_DBID_BOOTPARAMS;
if (strcmp (dbname, "netmasks") == 0)
}
-const char * __nss_dbop_to_name (int dbid, int search_fnum)
+const char ** __nss_get_dbtable (int dbid)
{
- // TODO
- switch (dbid)
- {
- case NSS_DBID_AUTH_ATTR:
- case NSS_DBID_AUTOMOUNT:
- case NSS_DBID_BOOTPARAMS:
- case NSS_DBID_NETMASKS:
- case NSS_DBID_PRINTERS:
- case NSS_DBID_PROF_ATTR:
- case NSS_DBID_PROJECT:
- break;
- }
+ static const char * __nss_dbtables[_NSS_DBID_MAX][_NSS_DBENTRY_MAX] = {
+ {NULL, NULL, NULL, NULL, "getauthattrbyname", NULL}, /* auth_attr */
+ {NULL, "bootparams_getbyname", NULL, NULL, NULL, NULL}, /* bootparams */
+ {NULL, "getnetmaskbynet", NULL, NULL, NULL, NULL}, /* netmasks */
+ {NULL, NULL, NULL, NULL, "getprinterbyname", NULL}, /* printers */
+ {NULL, NULL, NULL, NULL, "getprofname", NULL}, /* prof_attr */
+ {NULL, NULL, NULL, NULL, "getprojbyname", "getprojbyid"} /* project */
+ };
- return NULL;
+ if (dbid < 0 || dbid > _NSS_DBID_MAX)
+ return NULL;
+
+ return __nss_dbtables[dbid];
}
-db_lookup_function __nss_dbname_to_lookup (const char *dbname)
+db_lookup_function __nss_get_dblookupfunc (int dbid)
{
extern int internal_function __nss_auth_attr_lookup (service_user **,
const char *, void **);
- extern int internal_function __nss_automount_lookup (service_user **,
- const char *, void **);
extern int internal_function __nss_bootparams_lookup (service_user **,
const char *, void **);
extern int internal_function __nss_netmasks_lookup (service_user **,
extern int internal_function __nss_project_lookup (service_user **,
const char *, void **);
- int dbid = __nss_dbname_to_dbid (dbname);
- if (dbid == -1)
- return NULL;
-
switch (dbid)
{
case NSS_DBID_AUTH_ATTR:
return __nss_auth_attr_lookup;
- case NSS_DBID_AUTOMOUNT:
- return __nss_automount_lookup;
case NSS_DBID_BOOTPARAMS:
return __nss_bootparams_lookup;
case NSS_DBID_NETMASKS:
#include <nss_sunP.h>
#include <string.h>
#include <bits/libc-lock.h>
+#include <atomic.h>
+#include <assert.h>
nss_status_t nss_search (nss_db_root_t *rootp, nss_db_initf_t initf,
int search_fnum, void *search_args)
{
+ __libc_lock_lock (rootp->lock);
+
+ /* If we've never called nss_search then the context is NULL. */
+ if (rootp->s == NULL)
+ {
+ /* Determine dbid. */
+ nss_db_params_t conf;
+ initf (&conf);
+ int dbid = __nss_get_dbid (conf.name);
+ if (dbid == -1)
+ {
+ __libc_lock_unlock (rootp->lock);
+ return NSS_ERROR;
+ }
+
+ /* Allocate context. */
+ rootp->s = malloc (sizeof (struct nss_db_state));
+ if (!rootp->s)
+ {
+ __libc_lock_unlock (rootp->lock);
+ return NSS_ERROR;
+ }
+ struct nss_db_state *ctx = rootp->s;
+ memset (ctx, 0, sizeof (*ctx));
+
+ /* Get db lookup func. */
+ ctx->dblookupfunc = __nss_get_dblookupfunc (dbid);
+
+ /* Get dbtable. */
+ ctx->dbtable = __nss_get_dbtable (dbid);
+ assert (ctx->dbtable);
+ }
+
+ struct nss_db_state *ctx = rootp->s;
+
+ /* Make sure we know about search_fnum. */
+ if (search_fnum < 0 || search_fnum >= _NSS_DBENTRY_MAX)
+ return NSS_ERROR;
+ const char *searchfuncname = ctx->dbtable[search_fnum];
+
+ nss_XbyY_args_t* nssargs = (nss_XbyY_args_t *)search_args;
+
+ /* The rest of this is based on the code in nss/getXXbyYY_r.c. */
+
+ service_user *nip;
+ union
+ {
+ lookup_function l;
+ void *ptr;
+ } fct;
+
+ int no_more;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+
+ if (!ctx->startp_initialized)
+ {
+ no_more = ctx->dblookupfunc (&nip, searchfuncname, &fct.ptr);
+ if (no_more)
+ {
+ void *tmp_ptr = (service_user *) -1l;
+ PTR_MANGLE (tmp_ptr);
+ ctx->startp = tmp_ptr;
+ }
+ else
+ {
+ void *tmp_ptr = fct.l;
+ PTR_MANGLE (tmp_ptr);
+ ctx->start_fct = tmp_ptr;
+ tmp_ptr = nip;
+ PTR_MANGLE (tmp_ptr);
+ ctx->startp = tmp_ptr;
+ }
+
+ /* Make sure start_fct and startp are written before
+ startp_initialized. */
+ atomic_write_barrier ();
+ ctx->startp_initialized = true;
+ }
+ else
+ {
+ fct.l = ctx->start_fct;
+ PTR_DEMANGLE (fct.l);
+ nip = ctx->startp;
+ PTR_DEMANGLE (nip);
+ no_more = nip == (service_user *) -1l;
+ }
+
+ while (no_more == 0)
+ {
+ status = DL_CALL_FCT (fct.l, (nssargs->buf.result, nssargs->buf.buffer,
+ nssargs->buf.buflen, &errno));
+
+ /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
+ provided buffer is too small. In this case we should give
+ the user the possibility to enlarge the buffer and we should
+ not simply go on with the next service (even if the TRYAGAIN
+ action tells us so). */
+ if (status == NSS_STATUS_TRYAGAIN && errno == ERANGE)
+ break;
+
+ no_more = __nss_next (&nip, searchfuncname, &fct.ptr, status, 0);
+ }
+
+ nss_status_t res;
+ if (status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
+ res = NSS_SUCCESS;
+ else
+ res = NSS_ERROR;
+
+ if (errno == ERANGE && status != NSS_STATUS_TRYAGAIN)
+ __set_errno (EINVAL);
+
+ return res;
}
/* If we've never called nss_setent then the context is NULL. */
if (contextpp->ctx == NULL)
{
+ /* Get dbid. */
+ nss_db_params_t conf;
+ initf (&conf);
+ int dbid = __nss_get_dbid (conf.name);
+ if (dbid == -1)
+ return NSS_ERROR;
+
/* Allocate context. */
contextpp->ctx = malloc (sizeof (struct nss_getent_context));
if (!contextpp->ctx)
memset (ctx, 0, sizeof (*ctx));
/* Construct names. */
- nss_db_params_t conf;
- initf (&conf);
sprintf (ctx->getfuncname, "get%sent", conf.name);
sprintf (ctx->setfuncname, "set%sent", conf.name);
sprintf (ctx->endfuncname, "end%sent", conf.name);
/* Get db lookup func. */
- ctx->dblookup = __nss_dbname_to_lookup (conf.name);
+ ctx->dblookupfunc = __nss_get_dblookupfunc (dbid);
}
struct nss_getent_context *ctx = contextpp->ctx;
- __nss_setent (ctx->setfuncname, ctx->dblookup, &ctx->nip, &ctx->startp,
+ __nss_setent (ctx->setfuncname, ctx->dblookupfunc, &ctx->nip, &ctx->startp,
&ctx->last_nip, ctx->stayopen, &ctx->stayopen_tmp, 0);
__libc_lock_unlock (contextpp->lock);
char getfuncname[30];
char setfuncname[30];
char endfuncname[30];
- db_lookup_function dblookup;
+ db_lookup_function dblookupfunc;
service_user *nip;
service_user *last_nip;
int stayopen_tmp;
};
+typedef enum nss_status (*lookup_function) (void *, char *, size_t, int *);
+
+struct nss_db_state
+ {
+ bool startp_initialized;
+ service_user *startp;
+ lookup_function start_fct;
+
+ db_lookup_function dblookupfunc;
+ const char **dbtable;
+ };
+
#define RESULT_TO_STATUS(res) \
((res == 0) ? NSS_SUCCESS : (res == ENOENT) ? NSS_TRYAGAIN : NSS_ERROR)
NSS_DBID_NETMASKS,
NSS_DBID_PRINTERS,
NSS_DBID_PROF_ATTR,
- NSS_DBID_PROJECT
+ NSS_DBID_PROJECT,
+ _NSS_DBID_MAX = NSS_DBID_PROJECT
};
-extern int __nss_dbname_to_dbid (const char *dbname);
-extern const char * __nss_dbop_to_name (int dbid, int search_fnum);
-extern db_lookup_function __nss_dbname_to_lookup (const char * dbname);
+#define _NSS_DBENTRY_MAX 6
+
+extern int __nss_get_dbid (const char *dbname);
+extern const char ** __nss_get_dbtable (int dbid);
+extern db_lookup_function __nss_get_dblookupfunc (int dbid);
#endif /* _NSS_SUNP_H */