From murray@mother.cdrom.com  Wed Mar 22 03:46:12 2000
Return-Path: <murray@mother.cdrom.com>
Received: from mother.cdrom.com (mother.cdrom.com [204.216.28.172])
	by hub.freebsd.org (Postfix) with ESMTP id 7ACFC37BB66
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 22 Mar 2000 03:46:10 -0800 (PST)
	(envelope-from murray@mother.cdrom.com)
Received: (from murray@localhost)
	by mother.cdrom.com (8.9.3/8.9.3) id DAA77551;
	Wed, 22 Mar 2000 03:47:55 -0800 (PST)
	(envelope-from murray)
Message-Id: <200003221147.DAA77551@mother.cdrom.com>
Date: Wed, 22 Mar 2000 03:47:55 -0800 (PST)
From: murray@cdrom.com
Sender: murray@mother.cdrom.com
Reply-To: murray@cdrom.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: [patch] NIS configuration in sysinstall
X-Send-Pr-Version: 3.2

>Number:         17546
>Category:       bin
>Synopsis:       [sysinstall] sysinstall does not let you configure NIS
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 22 03:50:01 PST 2000
>Closed-Date:    Sun Dec 14 22:07:41 UTC 2008
>Last-Modified:  Sun Dec 14 22:07:41 UTC 2008
>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:
Responsible-Changed-From-To: freebsd-bugs->murray 
Responsible-Changed-By: murray 
Responsible-Changed-When: Fri Apr 7 16:43:07 PDT 2000 
Responsible-Changed-Why:  
I have some more work to do before committing this patch. 
Responsible-Changed-From-To: murray->eric 
Responsible-Changed-By: murray 
Responsible-Changed-When: Thu Aug 30 15:48:15 PDT 2001 
Responsible-Changed-Why:  
Eric is working on sysinstall now. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=17546 
Responsible-Changed-From-To: eric->freebsd-qa 
Responsible-Changed-By: eric 
Responsible-Changed-When: Mon Oct 1 12:01:54 PDT 2001 
Responsible-Changed-Why:  
assign idle sysinstall bugs to freebsd-qa, as suggested by murray 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=17546 
Responsible-Changed-From-To: freebsd-qa->qa 
Responsible-Changed-By: johan 
Responsible-Changed-When: Sat Aug 24 19:15:41 PDT 2002 
Responsible-Changed-Why:  
Use short names for mailing list to make searches    
using the web query form work with the shown responsible. 

This also makes open PRs show up in the summery mail. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=17546 
State-Changed-From-To: open->closed 
State-Changed-By: murray 
State-Changed-When: Sun Dec 14 22:06:17 UTC 2008 
State-Changed-Why:  
This patch is less relevant now with the current state of sysinstall 
and popularity of NIS.  Work should instead go into more promising 
future installers for FreeBSD. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=17546 
>Unformatted:
