Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Mar 2000 03:47:55 -0800 (PST)
From:      murray@cdrom.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/17546: [patch] NIS configuration in sysinstall
Message-ID:  <200003221147.DAA77551@mother.cdrom.com>

next in thread | raw e-mail | index | archive | help

>Number:         17546
>Category:       bin
>Synopsis:       Sysinstall does not let you configure NIS
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 22 03:50:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Murray Stokely
>Release:        FreeBSD 4.0-RELEASE i386
>Organization:
BSD, Inc?
>Environment:

  It looks like someone broke kget.c in -current but otherwise this
patch applies and builds cleanly.

>Description:

  This patch adds a NIS configuration menu after you select NIS client
in Startup configuration.  From this menu you can add NIS users and
netgroups to be imported to your system.  Currently there is no way to
add NIS users through sysinstall since the existing user management
functions call 'pw' which won't accept special characters like '+',
"@", or "-".  The new NIS-aware functions edit master.passwd directly
and then call pwd_mkdb.

  user.c is _really_ gross, and this patch does not help.

>How-To-Repeat:

  Try to setup NIS under FreeBSD without editing text files.

>Fix:

diff -ruN sysinstall.orig/menus.c sysinstall/menus.c
--- sysinstall.orig/menus.c	Wed Mar 22 14:40:06 2000
+++ sysinstall/menus.c	Wed Mar 22 19:01:55 2000
@@ -1284,7 +1284,7 @@
       { " named flags",	"Set default flags to named (if enabled)",
 	dmenuVarCheck, dmenuISetVariable, NULL, "named_flags" },
       { " nis client",	"This host wishes to be an NIS client.",
-	dmenuVarCheck, dmenuToggleVariable, NULL, "nis_client_enable=YES" },
+	NULL,	dmenuSubmenu, NULL, &MenuNIS, NULL },
       { " nis domainname",	"Set NIS domainname (if enabled)",
 	dmenuVarCheck, dmenuISetVariable, NULL, "nisdomainname" },
       { " nis server",	"This host wishes to be an NIS server.",
@@ -1310,6 +1310,27 @@
       { NULL } },
 };
 
+DMenu MenuNIS = {
+    DMENU_NORMAL_TYPE | DMENU_SELECTION_RETURNS,
+    "Network Information System Configuration.",
+    " ",
+    NULL,
+    NULL,
+    { { "X Exit", "Exit this menu (returning to previous)",
+	NULL, dmenuExit },
+      { "1 enable", "Enable NIS client services.",
+	dmenuVarCheck, dmenuSetVariable, NULL, "nis_client_enable=YES" },
+      { "2 disable", "Disable NIS client services.",
+	dmenuVarCheck, dmenuSetVariable, NULL, "nis_client_enable=NO" },
+      { "3 setdomainname",  "Set NIS domainname.",
+	dmenuVarCheck, dmenuISetVariable, NULL, "nisdomainname" },
+      { "4 addusers", "Add all NIS users.",
+	dmenuVarCheck, NISAddUsers, NULL, "nis_client_enable" },
+      { "5 adduser", "Add a NIS user.",
+	NULL, userAddUser, NULL, (int *)TRUE },
+      { NULL } },
+};
+
 DMenu MenuNetworking = {
     DMENU_CHECKLIST_TYPE | DMENU_SELECTION_RETURNS,
     "Network Services Menu",
@@ -1606,7 +1627,7 @@
     "Configure your user groups and users",
     NULL,
     { { "X Exit",	"Exit this menu (returning to previous)", NULL, dmenuExit },
-      { "User",		"Add a new user to the system.",	NULL, userAddUser },
+      { "User",		"Add a new user to the system.",	NULL, userAddUser, NULL, (int *)FALSE },
       { "Group",	"Add a new user group to the system.",	NULL, userAddGroup },
       { NULL } },
 };
diff -ruN sysinstall.orig/sysinstall.h sysinstall/sysinstall.h
--- sysinstall.orig/sysinstall.h	Sun Mar 12 03:57:26 2000
+++ sysinstall/sysinstall.h	Wed Mar 22 18:58:01 2000
@@ -377,6 +377,7 @@
 extern DMenu		MenuSysconsKeyrate;	/* System console keyrate configuration menu	*/
 extern DMenu		MenuSysconsSaver;	/* System console saver configuration menu	*/
 extern DMenu		MenuSysconsScrnmap;	/* System console screenmap configuration menu	*/
+extern DMenu            MenuNIS;                /* Network Information Service menu */
 extern DMenu		MenuNetworking;		/* Network configuration menu			*/
 extern DMenu		MenuInstallCustom;	/* Custom Installation menu			*/
 extern DMenu		MenuDistributions;	/* Distribution menu				*/
@@ -734,6 +735,9 @@
 /* user.c */
 extern int	userAddGroup(dialogMenuItem *self);
 extern int	userAddUser(dialogMenuItem *self);
+extern int      NISAddUsers(dialogMenuItem *self);
+extern void     NISAddUser(WINDOW *ds_win);
+extern int      NISverifyUserSettings(WINDOW *ds_win);
 
 /* variable.c */
 extern void	variable_set(char *var, int dirty);
diff -ruN sysinstall.orig/user.c sysinstall/user.c
--- sysinstall.orig/user.c	Sat Aug 28 01:34:21 1999
+++ sysinstall/user.c	Wed Mar 22 19:07:54 2000
@@ -39,6 +39,7 @@
 #include <ctype.h>
 #include <sys/param.h>
 #include <sysexits.h>
+#include <pwd.h>
 
 /* The help file for the user mgmt screen */
 #define USER_HELPFILE		"usermgmt"
@@ -69,6 +70,7 @@
 	umemb[UMEMB_FIELD_LEN],
 	homedir[HOMEDIR_FIELD_LEN],
 	shell[SHELL_FIELD_LEN];
+
 #define CLEAR(v)	memset(v, 0, sizeof v)
 
 static int	okbutton, cancelbutton;
@@ -150,6 +152,47 @@
     { NULL },
 };
 
+/* The NIS user configuration menu. */
+static Layout NISuserLayout[] = {
+#define LAYOUT_UNAME		0
+    { 3, 6, UT_NAMESIZE, UT_NAMESIZE + 1,
+      "Login ID:", "The login name of the new user (appended with a '+')",
+      uname, STRINGOBJ, NULL },
+#define LAYOUT_UID		1
+    { 3, 23, 8, UID_FIELD_LEN - 1,
+      "UID:", "The numerical ID for this user (leave blank to use server's setting)",
+      uid, STRINGOBJ, NULL },
+#define LAYOUT_UGROUP		2
+    { 3, 33, 8, UGROUP_FIELD_LEN - 1,
+      "Group:", "The login group name for this user (leave blank to use server's setting)",
+      ugroup, STRINGOBJ, NULL },
+#define LAYOUT_GECOS		4
+    { 8, 6, 33, GECOS_FIELD_LEN - 1,
+      "Full name:", "The user's full name (comment)",
+      gecos, STRINGOBJ, NULL },
+#define LAYOUT_UMEMB		5
+    { 8, 43, 15, UMEMB_FIELD_LEN - 1,
+      "Member groups:", "The groups this user belongs to (i.e. gets access rights for)",
+      umemb, STRINGOBJ, NULL },
+#define LAYOUT_HOMEDIR		6
+    { 13, 6, 20, HOMEDIR_FIELD_LEN - 1,
+      "Home directory:", "The user's home directory (leave blank to use server's setting)",
+      homedir, STRINGOBJ, NULL },
+#define LAYOUT_SHELL		7
+    { 13, 29, 29, SHELL_FIELD_LEN - 1,
+      "Login shell:", "The user's login shell (leave blank to use server's setting)",
+      shell, STRINGOBJ, NULL },
+#define LAYOUT_U_OKBUTTON	8
+    { 18, 15, 0, 0,
+      "OK", "Select this if you are happy with these settings",
+	&okbutton, BUTTONOBJ, NULL },
+#define LAYOUT_U_CANCELBUTTON	9
+    { 18, 35, 0, 0,
+      "CANCEL", "Select this if you wish to cancel this screen",
+      &cancelbutton, BUTTONOBJ, NULL },
+    { NULL },
+};
+
 /* whine */
 static void
 feepout(char *msg)
@@ -654,14 +697,18 @@
 {
     WINDOW              *ds_win, *save;
     ComposeObj          *obj = NULL;
-    int                 n = 0, cancel = FALSE, ret;
+    int                 n = 0, cancel = FALSE, isNIS, ret;
     int			max, firsttime = TRUE;
+    Layout              *layout;
 
     if (RunningAsInit && !strstr(variable_get(SYSTEM_STATE), "install")) {
         msgConfirm("This option may only be used after the system is installed, sorry!");
         return DITEM_FAILURE;
     }
 
+    isNIS=(int)self->data;
+    layout = isNIS ? NISuserLayout : userLayout;
+
     save = savescr();
     dialog_clear_norefresh();
 
@@ -689,25 +736,27 @@
     CLEAR(shell);
 
     /* Some more initialisation before we go into the main input loop */
-    obj = initLayoutDialog(ds_win, userLayout, USER_DIALOG_X, USER_DIALOG_Y, &max);
+    obj = initLayoutDialog(ds_win, layout, USER_DIALOG_X, USER_DIALOG_Y, &max);
     
 reenter:
     cancelbutton = okbutton = 0;
-    if (firsttime) {
-	/* fill in the blanks, well, just the GID */
-	completeUser();
-	RefreshStringObj(userLayout[LAYOUT_UID].obj);
-	RefreshStringObj(userLayout[LAYOUT_UGROUP].obj);
-	RefreshStringObj(userLayout[LAYOUT_GECOS].obj);
-	RefreshStringObj(userLayout[LAYOUT_UMEMB].obj);
-	RefreshStringObj(userLayout[LAYOUT_HOMEDIR].obj);
-	RefreshStringObj(userLayout[LAYOUT_SHELL].obj);
-	firsttime = FALSE;
+    if (firsttime && !isNIS) {
+      /* fill in the blanks, well, just the GID */
+      completeUser();
+      RefreshStringObj(layout[LAYOUT_UID].obj);
+      RefreshStringObj(layout[LAYOUT_UGROUP].obj);
+      RefreshStringObj(layout[LAYOUT_GECOS].obj);
+      RefreshStringObj(layout[LAYOUT_UMEMB].obj);
+      RefreshStringObj(layout[LAYOUT_HOMEDIR].obj);
+      RefreshStringObj(layout[LAYOUT_SHELL].obj);
+      firsttime = FALSE;
     }
 
-    while (layoutDialogLoop(ds_win, userLayout, &obj, &n, max, &cancelbutton, &cancel));
+    while (layoutDialogLoop(ds_win, layout, &obj, &n, max, &cancelbutton, &cancel));
 
-    if (!cancel && !verifyUserSettings(ds_win))
+    if (isNIS && !cancel && !NISverifyUserSettings(ds_win))
+	goto reenter;
+    else if (!cancel && !verifyUserSettings(ds_win))
 	goto reenter;
 
     /* Clear this crap off the screen */
@@ -716,12 +765,155 @@
     use_helpfile(NULL);
 
     if (!cancel) {
-	addUser(ds_win);
-	ret = DITEM_SUCCESS;
+        if (isNIS)
+	  NISAddUser(ds_win);
+	else 
+	  addUser(ds_win);
+	ret = DITEM_SUCCESS | DITEM_RESTORE;
     }
     else
 	ret = DITEM_FAILURE;
     restorescr(save);
+
     return ret;
 }
 
+/*
+ * The above code uses 'pw', which complains about the special characters [+@]
+ * that appear in NIS names.  Hence special NIS functions are created to write
+ * directly to master.passwd instead. 
+ */
+
+static int
+NISUserExist(char *login,FILE *passwdfp)
+{
+    char pwline[256];
+
+    rewind(passwdfp);
+    while (fgets(&pwline[0],256,passwdfp) != NULL) {
+      if (!strncmp(login,pwline,strlen(login))) {
+	/* An entry already exists for this user */
+	return 1;
+      }
+    }
+    return 0;
+}
+
+int
+NISAddUsers(dialogMenuItem *self)
+{
+    FILE *fptr;
+    long fpos;
+
+    WINDOW *w = savescr();
+
+    dialog_clear_norefresh();
+
+    /* Check to see if global NIS entry already exists */    
+    fptr = fopen(_PATH_MASTERPASSWD,"a+");
+    if (! fptr) {
+	msgConfirm("Could not open master password file.");
+	return DITEM_FAILURE;
+    }
+    fpos=ftell(fptr);
+
+    /* If there are no global NIS entries, add one. */
+    if (!NISUserExist("+",fptr)) {
+      msgConfirm("This option will import the entire NIS passwd map.  All users with NIS\n"
+	       "accounts on your network will be able to logon to your system.  If this\n"
+	       "is not desireable you should import individual NIS accounts instead.\n");
+
+      fseek(fptr,fpos,SEEK_SET);
+      fprintf(fptr,"+:::::::::\n");
+      fclose(fptr);
+      msgNotify("Remaking password file: %s", _PATH_MASTERPASSWD);
+      vsystem("pwd_mkdb -p %s", _PATH_MASTERPASSWD);
+      msgNotify("Password file rebuilt.");
+    } else {
+      msgConfirm("There is already a global NIS entry.  Password file untouched.");
+      fclose(fptr);
+    }
+
+
+    restorescr(w);
+    return DITEM_SUCCESS | DITEM_RESTORE;
+}
+
+void
+NISAddUser(WINDOW *ds_win)
+{
+    FILE *fptr;
+    long fpos;
+
+    WINDOW *w = savescr();
+
+    dialog_clear_norefresh();
+
+    /* Check to see if global NIS entry already exists */    
+    fptr = fopen(_PATH_MASTERPASSWD,"a+");
+    if (! fptr) {
+	msgConfirm("Could not open master password file.");
+	return;
+    }
+    fpos=ftell(fptr);
+
+    /* If there are no global NIS entries, add one. */
+    if (!NISUserExist(uname,fptr)) {
+      fseek(fptr,fpos,SEEK_SET);
+      fprintf(fptr,"%s:%s:%s:%s::0:0:%s:%s:%s\n",uname,passwd,uid,ugroup,gecos,homedir,shell);
+      fclose(fptr);
+      msgNotify("Remaking password file: %s", _PATH_MASTERPASSWD);
+      vsystem("pwd_mkdb -p %s", _PATH_MASTERPASSWD);
+      msgConfirm("User successfully added!");
+    } else {
+      msgConfirm("User %s already exists!",uname);
+      fclose(fptr);
+    }
+
+    restorescr(w);
+}
+
+int
+NISverifyUserSettings(WINDOW *ds_win)
+{
+    char *cp;
+    WINDOW *save;
+    int rv;
+
+    if (strlen(uname) == 0) {
+	feepout("The user name field must not be empty!");
+	return 0;
+    }
+    if ((uname[0] != '+') && (uname[0] != '-')) {
+      feepout("Valid NIS user names must start with a '+' or '-'!");
+      return 0;
+    }
+    if (strlen(shell) > 0) {
+	while((cp = getusershell()) != NULL)
+	    if (strcmp(cp, shell) == 0)
+		break;
+	endusershell();
+	if (cp == NULL) {
+	    save = savescr();
+	    rv = msgYesNo("Warning:\n\n"
+			  "The requested shell \"%s\" is not\n"
+			  "a valid user shell.\n\n"
+			  "Use it anyway?\n", shell);
+	    restorescr(save);
+	    wrefresh(ds_win);
+	    if (rv != DITEM_SUCCESS)
+		return 0;
+	}
+	
+    }
+
+    if (strlen(umemb) > 0) {
+	if (strpbrk(umemb, " \t") != NULL) {
+	    feepout("The member groups list must not contain any whitespace;\n"
+		    "use commas to separate the names.");
+	    return 0;
+	}
+    }
+
+    return 1;
+}


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200003221147.DAA77551>