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.