/* -*-c-*-
*
- * $Id: userdb.c,v 1.1 1997/07/21 13:47:43 mdw Exp $
+ * $Id: userdb.c,v 1.3 1997/08/07 09:44:29 mdw Exp $
*
* User database management
*
* (c) 1997 EBI
*/
-/*----- Licencing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of `become'
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with `become'; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with `become'; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*----- Revision history --------------------------------------------------*
*
* $Log: userdb.c,v $
- * Revision 1.1 1997/07/21 13:47:43 mdw
+ * Revision 1.3 1997/08/07 09:44:29 mdw
+ * Read NIS-based passwords from the YP server directly, rather than using
+ * `popen(ypcat)', which is probably both slower and less secure.
+ *
+ * Revision 1.2 1997/08/04 10:24:26 mdw
+ * Sources placed under CVS control.
+ *
+ * Revision 1.1 1997/07/21 13:47:43 mdw
* Initial revision
*
*/
/* --- Unix headers --- */
+#include "config.h"
+
#include <sys/types.h>
+#ifdef HAVE_YP
+# include <rpc/rpc.h>
+# include <rpcsvc/ypclnt.h>
+# include <rpcsvc/yp_prot.h>
+#endif
+
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
/* --- Local headers --- */
-#include "config.h"
+#include "become.h"
#include "sym.h"
#include "userdb.h"
#include "utils.h"
/* --- @userdb__dumpUser@ --- *
*
* Arguments: @const struct passwd *pw@ = pointer to a user block
- * @FILE *fp@ = pointer to stream to write on
*
* Returns: ---
*
* Use: Writes a user's informationt to a stream.
*/
-#ifndef NDEBUG
+#ifdef TRACING
-static void userdb__dumpUser(const struct passwd *pw, FILE *fp)
+static void userdb__dumpUser(const struct passwd *pw)
{
- printf("\n"
- "*** name == %s\n"
- "*** passwd == %s\n"
- "*** uid == %i\n"
- "*** gid == %i\n"
- "*** gecos == %s\n"
- "*** home == %s\n"
- "*** shell == %s\n",
- pw->pw_name, pw->pw_passwd, (int)pw->pw_uid, (int)pw->pw_gid,
- pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+ trace(TRACE_DEBUG,
+ "debug: name `%s' passwd `%s' uid %i gid %i",
+ pw->pw_name, pw->pw_passwd, (int)pw->pw_uid, (int)pw->pw_gid);
+ trace(TRACE_DEBUG,
+ "debug: ... gecos `%s' home `%s' shell `%s'",
+ pw->pw_gecos, pw->pw_dir, pw->pw_shell);
}
-#else
-
-#define userdb__dumpUser(pw, fp) ((void)0)
-
#endif
/* --- @userdb_copyUser@ --- *
* Use: Writes a group's information to a stream.
*/
-#ifndef NDEBUG
+#ifdef TRACING
-static void userdb__dumpGroup(const struct group *gr, FILE *fp)
+static void userdb__dumpGroup(const struct group *gr)
{
char *const *p;
- printf("\n"
- "*** name == %s\n"
- "*** passwd == %s\n"
- "*** gid == %i\n"
- "*** members...\n",
+ trace(TRACE_DEBUG,
+ "debug: name `%s' passwd `%s' gid %i",
gr->gr_name, gr->gr_passwd, (int)gr->gr_gid);
for (p = gr->gr_mem; *p; p++)
- printf("*** %s\n", *p);
+ trace(TRACE_DEBUG,"debug: ... `%s'", *p);
}
-#else
-
-#define userdb__dumpUser(pw, fp) ((void)0)
-
#endif
/* --- @userdb_copyGroup@ --- *
free(gr);
}
-/*----- Higher-level functions --------------------------------------------*/
-
-/* --- @userdb_local@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Reads the local list of users into the maps.
- */
-
-void userdb_local(void)
-{
- D( printf("adding local users...\n"); )
-
- /* --- Fetch users first --- */
-
- {
- struct passwd *pw;
-
- setpwent();
- while ((pw = getpwent()) != 0) {
- D( userdb__dumpUser(pw, stdout); )
- if (!userdb__byName(&userdb__users, pw->pw_name))
- userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
- userdb_copyUser(pw));
- }
- endpwent();
- }
-
- /* --- Then fetch groups --- */
-
- {
- struct group *gr;
-
- setgrent();
- while ((gr = getgrent()) != 0) {
- D( userdb__dumpGroup(gr, stdout); )
- if (!userdb__byName(&userdb__groups, gr->gr_name))
- userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
- userdb_copyGroup(gr));
- }
- endgrent();
- }
-}
-
-/* --- @userdb__getLine@ --- *
- *
- * Arguments: @char *buff@ = pointer to buffer to read into
- * @size_t sz@ = size of the buffer
- * @FILE *fp@ = pointer to stream to read on
- *
- * Returns: Zero if something didn't work.
- *
- * Use: Reads a line into the buffer. If the line didn't fit, bits
- * of it are thrown away. The newline character is not
- * included.
- */
-
-static char *userdb__getLine(char *buff, size_t sz, FILE *fp)
-{
- if ((buff = fgets(buff, sz, fp)) == 0)
- return (0);
- sz = strlen(buff) - 1;
- if (buff[sz] == '\n')
- buff[sz] = 0;
- else for (;;) {
- int ch = getc(fp);
- if (ch == '\n' || ch == EOF)
- break;
- }
- return (buff);
-}
-
-/* --- @userdb_yp@ --- *
- *
- * Arguments: ---
- *
- * Returns: ---
- *
- * Use: Fetches the YP database of users.
- */
-
-void userdb_yp(void)
-{
-
-#ifdef HAVE_YP
-
- char line[1024];
- FILE *fp;
-
- D( printf("adding nis users\n"); )
-
- /* --- First, users --- */
-
- if ((fp = popen("ypcat passwd", "r")) != 0) {
- while (userdb__getLine(line, sizeof(line), fp)) {
- struct passwd *pw;
-
- if ((pw = userdb__buildUser(line)) != 0) {
- D( userdb__dumpUser(pw, stdout); )
- if (userdb__byName(&userdb__users, pw->pw_name))
- userdb_freeUser(pw);
- else
- userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
- }
- }
- pclose(fp);
- }
-
- /* --- Next, groups --- */
-
-
- if ((fp = popen("ypcat group", "r")) != 0) {
- while (userdb__getLine(line, sizeof(line), fp)) {
- struct group *gr;
-
- if ((gr = userdb__buildGroup(line)) != 0) {
- D( userdb__dumpGroup(gr, stdout); )
- if (userdb__byName(&userdb__groups, gr->gr_name))
- userdb_freeGroup(gr);
- else
- userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
- }
- }
- pclose(fp);
- }
-
-#endif
-
-}
+/*----- Answering queries -------------------------------------------------*/
/* --- @userdb_userByName@, @userdb_userById@ --- *
*
return (s ? s->rec : 0);
}
+/*----- Yellow pages support ----------------------------------------------*/
+
+#ifdef HAVE_YP
+
+/* --- @userdb__foreachUser@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachUser(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct passwd *pw;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
+ pw = userdb__buildUser(cv);
+ if (pw && !userdb__byName(&userdb__users, pw->pw_name)) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
+ }
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb__foreachGroup@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachGroup(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct group *gr;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
+ gr = userdb__buildGroup(cv);
+ if (gr && !userdb__byName(&userdb__groups, gr->gr_name)) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
+ }
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb_yp@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Fetches the YP database of users.
+ */
+
+void userdb_yp(void)
+{
+ char *ypdom;
+
+ /* --- Bind to a server --- */
+
+ if (yp_get_default_domain(&ypdom) ||
+ yp_bind(ypdom))
+ return;
+
+ T( trace(TRACE_DEBUG, "debug: adding NIS users"); )
+
+ /* --- Fetch the users map --- */
+
+ {
+ static struct ypall_callback ucb = { userdb__foreachUser, 0 };
+ yp_all(ypdom, "passwd.byuid", &ucb);
+ }
+
+ /* --- Fetch the groups map --- */
+
+ {
+ static struct ypall_callback gcb = { userdb__foreachGroup, 0 };
+ yp_all(ypdom, "group.bygid", &gcb);
+ }
+
+ yp_unbind(ypdom);
+}
+
+#else
+
+void userdb_yp(void) { ; }
+
+#endif
+
+/*----- Building the databases --------------------------------------------*/
+
+/* --- @userdb_local@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Reads the local list of users into the maps.
+ */
+
+void userdb_local(void)
+{
+ T( trace(TRACE_DEBUG, "debug: adding local users"); )
+
+ /* --- Fetch users first --- */
+
+ {
+ struct passwd *pw;
+
+ setpwent();
+ while ((pw = getpwent()) != 0) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
+ if (!userdb__byName(&userdb__users, pw->pw_name))
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
+ userdb_copyUser(pw));
+ }
+ endpwent();
+ }
+
+ /* --- Then fetch groups --- */
+
+ {
+ struct group *gr;
+
+ setgrent();
+ while ((gr = getgrent()) != 0) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
+ if (!userdb__byName(&userdb__groups, gr->gr_name))
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
+ userdb_copyGroup(gr));
+ }
+ endgrent();
+ }
+}
+
/* --- @userdb_init@ --- *
*
* Arguments: ---
void dumpit(const char *msg)
{
- printf("\n\n$$$ %s\n", msg);
+ trace(TRACE_DEBUG, "debug: %s", msg);
{
struct passwd *pw;
for (userdb_iterateUsers(); (pw = userdb_nextUser()) != 0; )
- userdb__dumpUser(pw, stdout);
+ userdb__dumpUser(pw);
}
{
struct group *gr;
for (userdb_iterateGroups(); (gr = userdb_nextGroup()) != 0; )
- userdb__dumpGroup(gr, stdout);
+ userdb__dumpGroup(gr);
}
}
int main(void)
{
+ ego("userdb-test");
+ traceon(stderr, TRACE_ALL);
userdb_init();
dumpit("cleared");
- userdb_local();
- dumpit("local");
userdb_yp();
dumpit("yp");
+ userdb_local();
+ dumpit("local");
return (0);
}