This is Users.m in view mode; [Download] [Up]
/*
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
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.