home *** CD-ROM | disk | FTP | other *** search
- /*
- SambaManger. A graphical frontend to configure the NetInfo enhanced samba.
- Copyright (C) 1998 Robert Frank
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Robert Frank, frank@ifi.unibas.ch
- */
-
- #import "Users.h"
- #import "Controller.h"
- #import "NIDirectory.h"
- #import "NIProperty.h"
- #import "NetInfoKeys.h"
- #import <sys/types.h>
- #import <pwd.h>
- #import <time.h>
- #import <strings.h>
- #import "cryptdefs.h"
- #import "ni_crypt.h"
-
- // The property names of a user's directory:
- #define U_NAME "name"
- #define U_PASSWD "passwd"
- #define U_UID "uid"
- #define U_GID "gid"
- #define U_REALNAME "realname"
- #define U_HOME "home"
- #define U_SHELL "shell"
- #define U_SMBPASSWD "smbpasswd"
- #define U_SMBNTPASSWD "smbntpasswd"
- #define U_WPASSWD "_writers_passwd"
- #define U_WSMBPASSWD "_writers_smbpasswd"
- #define U_WNTPASSWD "_writers_smbntpasswd"
-
- // Class variable with the string for the open/save panel's title.
- static const char *title;
-
- @implementation Users
-
- // ************************************************************************
- // Class methods:
- + initialize
- // Called once by the run time system
- {
- title = [Service stringFor:"Title:Users"];
- return self;
- }
-
- + new:sender at:(NXCoord *)offset
- {
- NIDirectory *NIDir;
- Users *user = [Users alloc];
-
- if ((NIDir = [NIDirectory new:sender root:SMNI_USERS directory:NULL])) {
- [NIDir setDelegate:user];
- if ([user init:sender dirObj:NIDir delta:offset service:NULL]) {
- [NIDir setSaveTitle:title];
- return user;
- }
- [NIDir close];
- }
- return [user free];
- }
-
- + open:sender at:(NXCoord *)offset
- {
- NIDirectory *NIDir;
- Users *user = [Users alloc];
-
- if ((NIDir = [NIDirectory open:sender root:SMNI_USERS withTitle:title])) {
- [NIDir setDelegate:user];
- if ([user init:sender dirObj:NIDir delta:offset service:[NIDir baseName]])
- return user;
-
- [NIDir close];
- }
- return [user free];
- }
-
-
- // Local methods:
- // We'll misuse the check for mandatory fields for password verification!
- // This way we don't need to override the save and saveToDomain methods.
- - (BOOL)minimumOK
- {
- int signal;
- char *passwd, *p;
- char salt[3];
- unsigned char new_p16[16], new_nt_p16[16], new_p32[34], new_nt_p32[34];
- struct timeval tp;
- struct timezone tzp;
- char sa[64] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
- 'n','o','p','q','r','s','t','u','v','w','x','y','z',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M',
- 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
- '0','1','2','3','4','5','6','7','8','9','.','/'};
-
- // Run a modal for the panel.
- [fieldVerifyPassword setStringValue:""];
- [fieldVerifyPassword selectText:self];
- signal = [NXApp runModalFor:password];
- [password close];
-
- switch (signal) {
- case NX_RUNABORTED:
- return NO;
- case NX_RUNSTOPPED:
- default: ;
- }
-
- // Passwords both identical?
- passwd = (char *)[fieldVerifyPassword stringValue];
- if (strcmp(passwd, [textSMBPasswd stringValue]))
- return NO;
-
- if ([checkPassword state]) {
- /* Encrypt the unix password. */
-
- /* Have to pick a new salt! */
- if (gettimeofday(&tp, &tzp) != 0)
- strncpy(salt, [[ni_dirObj property:U_PASSWD] valueAt:0], 2); /* Copy the old salt! */
-
- (void) srandom(tp.tv_sec);
- salt[0] = sa[random()%54];
- salt[1] = sa[random()%54];
- salt[2] = '\0';
-
- [[ni_dirObj property:U_PASSWD] updateValue:crypt((char *)passwd, salt) at:0];
- }
-
- memset(new_nt_p16, '\0', 16);
- E_md4hash((unsigned char *) passwd, new_nt_p16);
-
- // Mangle the passwords into Lanman format.
- passwd[14] = '\0';
- for (p = passwd; *p; p++)
- *p = NXToUpper(*p);
-
- // Calculate the SMB (lanman) hash functions of new password.
- memset(new_p16, '\0', 16);
- E_P16((unsigned char *) passwd, new_p16);
-
- // Create the 32 byte representation of the new p16.
- ni_encrypt(new_p16, new_p32);
-
- // Create the 32 byte representation of the new NT md4 hash.
- ni_encrypt(new_nt_p16, new_nt_p32);
-
- [[ni_dirObj property:U_SMBPASSWD] updateValue:new_p32 at:0];
- [[ni_dirObj property:U_SMBNTPASSWD] updateValue:new_nt_p32 at:0];
-
-
- return YES;
- }
-
- // ************************************************************************
- // Methods:
-
- - delete:sender
- {
- NXRunAlertPanel(getString("Alert:Alert"),
- getString("Message:Cannot delete users with SambaManager!"),
- getString("Button:OK"), NULL, NULL);
- return self;
- }
-
- - passwordCancel:sender
- {
- [NXApp abortModal];
- return self;
- }
-
- - passwordOK:sender
- {
- [NXApp stopModal];
- return self;
- }
-
- - installWithoutSetting:sender
- {
- char ud[1024], *dName;
- id status = nil;
- int len = strlen(userName);
- unsigned char new_p32[34], new_nt_p32[34];
-
- // Set ther user's name as the encoded(!) password
- // This is safe, as the name would be `decoded' before comparing to any
- // entered password.
- (void)strcpy(new_p32, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- (void)strcpy(new_nt_p32, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- bcopy(userName, new_p32, (len>32)?32:len);
- bcopy(userName, new_nt_p32, (len>32)?32:len);
-
-
- [[ni_dirObj property:U_SMBPASSWD] updateValue:new_p32 at:0];
- [[ni_dirObj property:U_SMBNTPASSWD] updateValue:new_nt_p32 at:0];
-
- // Save
- if (status = [ni_dirObj save]) {
- [window setDocEdited:NO];
- dName = (char *)[ni_dirObj domainName];
- sprintf(ud, "%s/%s", (dName && *dName && (dName[1] != '\0'))?dName:"", [ni_dirObj baseName]);
- [window setTitleAsFilename:ud];
- [buttonInstall setEnabled:NO];
- }
- return status;
- }
-
- - setupAndLoad
- {
- struct passwd *pwent;
-
- [ni_dirObj addString:U_REALNAME outlet:textFullName];
- userName = [[ni_dirObj addString:U_NAME outlet:textUserName] valueAt:0];
- [ni_dirObj addString:U_UID outlet:textUserID];
- [ni_dirObj addString:U_GID outlet:textDefaultGroup];
- [ni_dirObj addString:U_HOME outlet:textHomeDirectory];
- [ni_dirObj addString:U_SHELL outlet:textLoginShell];
-
- [buttonInstall setEnabled:![[ni_dirObj addProperty:U_SMBPASSWD] values]];
- [[ni_dirObj addProperty:U_WSMBPASSWD] updateValue:userName at:0];
- [ni_dirObj addProperty:U_SMBNTPASSWD];
- [[ni_dirObj addProperty:U_WNTPASSWD] updateValue:userName at:0];
- [ni_dirObj addProperty:U_PASSWD];
-
- pwent = getpwuid(getuid());
-
- // Future versions may allow any user for authentication, but
- // then only the passwords should be updated (and only if the
- // user is the same as given in the _writers properties).
- // [ni_dirObj setAuthenticationUser:pwent->pw_name];
-
- [ni_dirObj scan];
-
- [textUserName setEditable:NO];
- [textUserID setEditable:NO];
- [textFullName selectText:self];
-
- return self;
- }
-
- // ************************************************************************
- // Delegates:
- - textDidChange:sender
- {
- return self;
- }
-
- - textDidEnd:textObject endChar:(unsigned short)whyEnd
- {
- [NXApp stopModal];
- return self;
- }
-
-
- @end
-