home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Networking / SambaManager / Users.m < prev   
Encoding:
Text File  |  1998-03-28  |  7.3 KB  |  270 lines

  1. /*
  2.     SambaManger. A graphical frontend to configure the NetInfo enhanced samba.
  3.     Copyright (C) 1998  Robert Frank
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.         
  19.         Robert Frank, frank@ifi.unibas.ch
  20. */
  21.  
  22. #import "Users.h"
  23. #import "Controller.h"
  24. #import "NIDirectory.h"
  25. #import "NIProperty.h"
  26. #import "NetInfoKeys.h"
  27. #import <sys/types.h>
  28. #import <pwd.h>
  29. #import <time.h>
  30. #import <strings.h>
  31. #import "cryptdefs.h"
  32. #import "ni_crypt.h"
  33.  
  34. // The property names of a user's directory:
  35. #define U_NAME                "name"
  36. #define U_PASSWD            "passwd"
  37. #define U_UID                    "uid"
  38. #define U_GID                    "gid"
  39. #define U_REALNAME        "realname"
  40. #define U_HOME                "home"
  41. #define U_SHELL                "shell"
  42. #define U_SMBPASSWD        "smbpasswd"
  43. #define U_SMBNTPASSWD    "smbntpasswd"
  44. #define U_WPASSWD            "_writers_passwd"
  45. #define U_WSMBPASSWD    "_writers_smbpasswd"
  46. #define U_WNTPASSWD        "_writers_smbntpasswd"
  47.  
  48. // Class variable with the string for the open/save panel's title.
  49. static const char *title;
  50.  
  51. @implementation Users
  52.  
  53. // ************************************************************************
  54. // Class methods:
  55. + initialize
  56. // Called once by the run time system
  57. {
  58.         title = [Service stringFor:"Title:Users"];
  59.         return self;
  60. }
  61.  
  62. + new:sender at:(NXCoord *)offset
  63. {
  64. NIDirectory    *NIDir;
  65. Users                *user = [Users alloc];
  66.  
  67.         if ((NIDir = [NIDirectory new:sender root:SMNI_USERS directory:NULL])) {
  68.             [NIDir setDelegate:user];
  69.             if ([user init:sender dirObj:NIDir delta:offset service:NULL]) {
  70.                 [NIDir setSaveTitle:title];
  71.                 return user;
  72.             }
  73.             [NIDir close];
  74.         }
  75.         return [user free];
  76. }
  77.  
  78. + open:sender at:(NXCoord *)offset
  79. {
  80. NIDirectory    *NIDir;
  81. Users                *user = [Users alloc];
  82.  
  83.         if ((NIDir = [NIDirectory open:sender root:SMNI_USERS withTitle:title])) {        
  84.             [NIDir setDelegate:user];
  85.             if ([user init:sender dirObj:NIDir delta:offset service:[NIDir baseName]])
  86.                 return user;
  87.  
  88.             [NIDir close];
  89.         }
  90.         return [user free];
  91. }
  92.  
  93.  
  94. // Local methods:
  95. // We'll misuse the check for mandatory fields for password verification!
  96. // This way we don't need to override the save and saveToDomain methods.
  97. - (BOOL)minimumOK
  98. {
  99. int                            signal;
  100. char                        *passwd, *p;
  101. char                        salt[3];
  102. unsigned char        new_p16[16], new_nt_p16[16], new_p32[34], new_nt_p32[34];
  103. struct timeval    tp;
  104. struct timezone    tzp;
  105. char                        sa[64] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
  106.                                                     'n','o','p','q','r','s','t','u','v','w','x','y','z',
  107.                                                     'A','B','C','D','E','F','G','H','I','J','K','L','M',
  108.                                                     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  109.                                                     '0','1','2','3','4','5','6','7','8','9','.','/'};
  110.  
  111.         // Run a modal for the panel.
  112.         [fieldVerifyPassword setStringValue:""];
  113.         [fieldVerifyPassword selectText:self];
  114.         signal = [NXApp runModalFor:password];
  115.         [password close];
  116.  
  117.         switch (signal) {
  118.             case NX_RUNABORTED:
  119.                 return NO;
  120.             case NX_RUNSTOPPED: 
  121.             default: ;
  122.         }
  123.  
  124.         // Passwords both identical?
  125.         passwd = (char *)[fieldVerifyPassword stringValue];
  126.         if (strcmp(passwd, [textSMBPasswd stringValue]))
  127.             return NO;
  128.         
  129.         if ([checkPassword state]) {
  130.             /* Encrypt the unix password. */
  131.  
  132.             /* Have to pick a new salt! */
  133.             if (gettimeofday(&tp, &tzp) != 0)
  134.                 strncpy(salt, [[ni_dirObj property:U_PASSWD] valueAt:0], 2);    /* Copy the old salt! */
  135.             
  136.             (void) srandom(tp.tv_sec);
  137.             salt[0] = sa[random()%54];
  138.             salt[1] = sa[random()%54];
  139.             salt[2] = '\0';
  140.  
  141.             [[ni_dirObj property:U_PASSWD] updateValue:crypt((char *)passwd, salt) at:0];
  142.     }
  143.  
  144.         memset(new_nt_p16, '\0', 16);
  145.         E_md4hash((unsigned char *) passwd, new_nt_p16);
  146.         
  147.         // Mangle the passwords into Lanman format.
  148.         passwd[14] = '\0';
  149.         for (p = passwd; *p; p++)
  150.             *p = NXToUpper(*p);
  151.     
  152.         // Calculate the SMB (lanman) hash functions of new password.
  153.         memset(new_p16, '\0', 16);
  154.         E_P16((unsigned char *) passwd, new_p16);
  155.     
  156.         // Create the 32 byte representation of the new p16.
  157.         ni_encrypt(new_p16, new_p32);
  158.     
  159.         // Create the 32 byte representation of the new NT md4 hash.
  160.         ni_encrypt(new_nt_p16, new_nt_p32);
  161.  
  162.         [[ni_dirObj property:U_SMBPASSWD] updateValue:new_p32 at:0];
  163.         [[ni_dirObj property:U_SMBNTPASSWD] updateValue:new_nt_p32 at:0];
  164.  
  165.  
  166.         return YES;
  167. }
  168.  
  169. // ************************************************************************
  170. //    Methods:
  171.  
  172. - delete:sender
  173. {
  174.         NXRunAlertPanel(getString("Alert:Alert"),
  175.                                         getString("Message:Cannot delete users with SambaManager!"),
  176.                                         getString("Button:OK"), NULL, NULL);
  177.         return self;
  178. }
  179.  
  180. - passwordCancel:sender
  181. {
  182.         [NXApp abortModal];
  183.     return self;
  184. }
  185.  
  186. - passwordOK:sender
  187. {
  188.         [NXApp stopModal];
  189.         return self;
  190. }
  191.  
  192. - installWithoutSetting:sender
  193. {
  194. char                    ud[1024], *dName;
  195. id                        status = nil;
  196. int                        len = strlen(userName);
  197. unsigned char    new_p32[34], new_nt_p32[34];
  198.  
  199.         // Set ther user's name as the encoded(!) password
  200.         // This is safe, as the name would be `decoded' before comparing to any
  201.         // entered password.
  202.         (void)strcpy(new_p32, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
  203.         (void)strcpy(new_nt_p32, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
  204.         bcopy(userName, new_p32, (len>32)?32:len);
  205.         bcopy(userName, new_nt_p32, (len>32)?32:len);
  206.         
  207.  
  208.         [[ni_dirObj property:U_SMBPASSWD] updateValue:new_p32 at:0];
  209.         [[ni_dirObj property:U_SMBNTPASSWD] updateValue:new_nt_p32 at:0];
  210.  
  211.         // Save
  212.         if (status = [ni_dirObj save]) {
  213.             [window setDocEdited:NO];
  214.             dName = (char *)[ni_dirObj domainName];
  215.             sprintf(ud, "%s/%s", (dName && *dName && (dName[1] != '\0'))?dName:"", [ni_dirObj baseName]);
  216.             [window setTitleAsFilename:ud];
  217.             [buttonInstall setEnabled:NO];
  218.         }
  219.         return status;
  220. }
  221.  
  222. - setupAndLoad
  223. {
  224. struct passwd    *pwent;
  225.  
  226.         [ni_dirObj addString:U_REALNAME outlet:textFullName];
  227.         userName = [[ni_dirObj addString:U_NAME outlet:textUserName] valueAt:0];
  228.         [ni_dirObj addString:U_UID outlet:textUserID];
  229.         [ni_dirObj addString:U_GID outlet:textDefaultGroup];
  230.         [ni_dirObj addString:U_HOME outlet:textHomeDirectory];
  231.         [ni_dirObj addString:U_SHELL outlet:textLoginShell];
  232.  
  233.         [buttonInstall setEnabled:![[ni_dirObj addProperty:U_SMBPASSWD] values]];
  234.         [[ni_dirObj addProperty:U_WSMBPASSWD] updateValue:userName at:0];
  235.         [ni_dirObj addProperty:U_SMBNTPASSWD];
  236.         [[ni_dirObj addProperty:U_WNTPASSWD] updateValue:userName at:0];
  237.         [ni_dirObj addProperty:U_PASSWD];
  238.  
  239.         pwent = getpwuid(getuid());
  240.     
  241.         // Future versions may allow any user for authentication, but
  242.         // then only the passwords should be updated (and only if the
  243.         // user is the same as given in the _writers properties).
  244. //        [ni_dirObj setAuthenticationUser:pwent->pw_name];
  245.         
  246.         [ni_dirObj scan];
  247.         
  248.         [textUserName setEditable:NO];
  249.         [textUserID setEditable:NO];
  250.         [textFullName selectText:self];
  251.  
  252.         return self;
  253. }
  254.  
  255. // ************************************************************************
  256. // Delegates:
  257. - textDidChange:sender
  258. {
  259.         return self;
  260. }
  261.  
  262. - textDidEnd:textObject endChar:(unsigned short)whyEnd
  263. {
  264.         [NXApp stopModal];
  265.         return self;
  266. }
  267.  
  268.  
  269. @end
  270.