home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / dbsamp.exe / DBAPP / CLIENT / DBAPP.C < prev    next >
C/C++ Source or Header  |  1995-01-12  |  29KB  |  1,051 lines

  1. /****************************************************************************
  2. **    File:    DBAPP.C
  3. **
  4. **    Desc:        This is the CLIENT side of an NCP Extention server which authenticates
  5. **                    to services that are loaded as NetWare NLMs.  The user is looked up in
  6. **                    the "User" attribute of the Database to verify that the user has rights.
  7. **                    If the user has rights, access is granted.
  8. **
  9. **        DISCLAIMER
  10. **
  11. **    Novell, Inc. makes no representations or warranties with respect to
  12. **    any NetWare software, and specifically disclaims any express or
  13. **    implied warranties of merchantability, title, or fitness for a
  14. **    particular purpose.
  15. **
  16. **    Distribution of any NetWare software is forbidden without the
  17. **    express written consent of Novell, Inc.  Further, Novell reserves
  18. **    the right to discontinue distribution of any NetWare software.
  19. **
  20. **    Novell is not responsible for lost profits or revenue, loss of use
  21. **    of the software, loss of data, costs of re-creating lost data, the
  22. **    cost of any substitute equipment or program, or claims by any party
  23. **    other than you.  Novell strongly recommends a backup be made before
  24. **    any software is installed.   Technical support for this software
  25. **    may be provided at the discretion of Novell.
  26. **
  27. **    Programmers:
  28. **
  29. **        Ini    Who                                Firm
  30. **        --- ----------------- ------------------------------------------------
  31. **        CRG    Calvin Gaisford        Novell Developer Support
  32. **      KLB Karl L. Bunnell        Novell Developer Support
  33. **
  34. **    History:
  35. **
  36. **        When         Who What
  37. **        -------- --- ---------------------------------------------------------
  38. **        1-04-95  CRG Adapted rough code into generic example to be distributed.
  39. */
  40.  
  41.  
  42.  
  43. /***************************************************************************
  44. **  Libraries Linked in for .exe
  45. **
  46. **  NWCALLS.LIB
  47. **  NWLOCALE.LIB
  48. **  NWNET.LIB
  49. **
  50. */
  51.  
  52. /***************************************************************************
  53. **  #defines
  54. */
  55. #define NWWIN
  56. #define NCPEXTNAME    "DBSAuth"
  57. #define DO_AUTH            1
  58.  
  59.  
  60.  
  61. /****************************************************************************
  62. **    Include headers, macros, etc.
  63. */
  64.  
  65.     /*-----------------------------------------------------------------------
  66.     **    ANSI -- BORLAND/WINDOWS
  67.     */
  68.     #include <windows.h>
  69.     #include <bwcc.h>
  70.     #include <stdio.h>
  71.     #include <stdlib.h>
  72.     #include <string.h>
  73.     #include <conio.h>
  74.  
  75.     /*-----------------------------------------------------------------------
  76.     **    NetWare
  77.     */
  78.     #include <nwlocale.h>
  79.     #include <nwnet.h>
  80.     #include <nwcalls.h>
  81.     #include <nwncpext.h>
  82.  
  83.     /*-----------------------------------------------------------------------
  84.     **    Program
  85.     */
  86.     #include "dbapp.h"
  87.  
  88.  
  89.  
  90.     /***************************************************************************
  91. **    Type Definitions
  92. */
  93. typedef struct AUTHREQUEST {
  94.     unsigned short    Command;
  95.     char         objectName[516];
  96. } AUTHREQUEST;
  97.  
  98. typedef struct AUTHREPLY {
  99.     unsigned char    completionCode;     /* Zero means successful */
  100. } AUTHREPLY;
  101.  
  102.  
  103.  
  104. /***************************************************************************
  105. **    Global Storage
  106. */
  107. HANDLE hInst;
  108. int err;
  109. NWDSContextHandle        gContext;
  110. NWCONN_HANDLE            gConnHandle;
  111. char                        nContext[MAX_DN_CHARS];
  112.  
  113.  
  114.  
  115. /***************************************************************************
  116. **    Function Prototypes
  117. */
  118. BOOL CALLBACK NCPAuthDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam);
  119. BOOL CALLBACK DBFindDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam);
  120. WORD InitDialogStuff(HWND hDlg);
  121. WORD DoAuthentication(HWND hDlg);
  122. WORD DoUnAuthentication(HWND hDlg);
  123. WORD GetHostServer(char *objectName, char *hostServer);
  124. WORD GetConnectionHandle(char *nwServerName, NWCONN_HANDLE NWFAR *connHandle);
  125. WORD DoNCPCall(char *dbName, NWCONN_HANDLE NWFAR *connHandle);
  126. WORD ShowDBFindDialog(HWND hDlg);
  127. WORD UpdateDBFindDialog(HWND hDlg);
  128. WORD UpdateSelectedDatabase(HWND hDlg);
  129. WORD UpdateChangedContext(HWND hDlg);
  130. WORD HandleErrorMsg(char *funcName, char *message, NWDSCCODE ccode);
  131. WORD ReadStoredDatabaseName(HWND hDlg);
  132. WORD SetStoredDatabaseName(HWND hDlg);
  133.  
  134.  
  135.  
  136. #pragma argsused
  137. /***************************************************************************
  138. **  Main Windows proc.  Common to all Windows Apps.
  139. */
  140. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  141.     LPSTR lpszCmdLine, int nCmdShow)
  142. {
  143.     HWND        hwnd;
  144.     MSG        msg;
  145.     DLGPROC     dlgproc;
  146.  
  147.     (void) lpszCmdLine;
  148.     hInst = hInstance;
  149.     if (err != 0)
  150.         return 1;
  151.  
  152.     dlgproc = (DLGPROC) MakeProcInstance (NCPAuthDlgProc, hInstance);
  153.     hwnd = CreateDialog (hInstance, "NCPAUTH_DLG", GetDesktopWindow (), dlgproc);
  154.     ShowWindow (hwnd, nCmdShow);
  155.     UpdateWindow (hwnd);
  156.     while (GetMessage (&msg, NULL, 0, 0))
  157.     {
  158.         TranslateMessage (&msg);
  159.         DispatchMessage (&msg);
  160.     }
  161.     return msg.wParam;
  162. }
  163.  
  164.  
  165. /***************************************************************************
  166. **  Callback procedure to handle the Main Dialog for the Application.
  167. */
  168. BOOL CALLBACK NCPAuthDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
  169. {
  170.     char    nameBuf[MAX_DN_CHARS];
  171.  
  172.     switch (message)
  173.     {
  174.         case WM_CLOSE:
  175.             NWDSFreeContext(gContext);
  176.             EndDialog (hDlg, 0);
  177.             PostQuitMessage (0);
  178.             return TRUE;
  179.  
  180.         case WM_INITDIALOG:
  181.             InitDialogStuff(hDlg);
  182.             return TRUE;
  183.  
  184.         case WM_COMMAND:
  185.             switch (wParam)
  186.             {
  187.                 case DATABASE_NAME:
  188.                     if(HIWORD(lParam) == EN_CHANGE)
  189.                     {
  190.                         GetDlgItemText(hDlg, DATABASE_NAME, nameBuf, MAX_DN_CHARS);
  191.                         if(strlen(nameBuf))
  192.                             EnableWindow(GetDlgItem(hDlg, IDC_AUTH_BUT), TRUE);
  193.                         else
  194.                             EnableWindow(GetDlgItem(hDlg, IDC_AUTH_BUT), FALSE);
  195.                     }
  196.                     break;
  197.                 case IDC_AUTH_BUT:
  198.                     SetStoredDatabaseName(hDlg);
  199.                     DoAuthentication(hDlg);
  200.                     break;
  201.                 case IDC_UNAUTH_BUT:
  202.                     DoUnAuthentication(hDlg);
  203.                     break;
  204.                 case IDC_QUIT_BUT:
  205.                     NWDSFreeContext(gContext);
  206.                     EndDialog (hDlg, 0);
  207.                     PostQuitMessage (0);
  208.                     return TRUE;
  209.                 case IDC_LOCATE_BUT:
  210.                     ShowDBFindDialog(hDlg);
  211.                     return TRUE;
  212.             }
  213.             break;
  214.     }
  215.     return FALSE;
  216. }
  217.  
  218.  
  219. /***************************************************************************
  220. **  Callback Procedure for Browse dialog that pops up when the "Locate Dabase"
  221. **    button is pressed from the main dialog.
  222. */
  223. BOOL CALLBACK DBFindDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
  224. {
  225.     char                            dbName[MAX_DN_CHARS];
  226.     switch (message)
  227.     {
  228.         case WM_CLOSE:
  229.             EndDialog (hDlg, 0);
  230.             return TRUE;
  231.  
  232.         case WM_INITDIALOG:
  233.             UpdateDBFindDialog(hDlg);
  234.             return TRUE;
  235.  
  236.         case WM_COMMAND:
  237.             switch (wParam)
  238.             {
  239.                 case CANCEL_BUT:
  240.                     EndDialog (hDlg, 0);
  241.                     return TRUE;
  242.  
  243.                 case CONTAINER_LIST:
  244.                     if (HIWORD (lParam) == LBN_DBLCLK) /* Double Click*/
  245.                     {
  246.                         UpdateChangedContext(hDlg);
  247.                         UpdateDBFindDialog(hDlg);
  248.                     }
  249.                     break;
  250.  
  251.                 case DATABASE_LIST:
  252.                     if (HIWORD (lParam) == LBN_SELCHANGE)
  253.                     {
  254.                         UpdateSelectedDatabase(hDlg);
  255.                     }
  256.                     if (HIWORD (lParam) == LBN_DBLCLK)
  257.                     {
  258.                         UpdateSelectedDatabase(hDlg);
  259.                         GetDlgItemText(hDlg, SELECTED_DATABASE, dbName, MAX_DN_CHARS);
  260.                         SetDlgItemText(GetParent(hDlg), DATABASE_NAME, dbName);
  261.                         EndDialog (hDlg, 0);
  262.                     }
  263.                     break;
  264.  
  265.                 case SELECT_BUT:
  266.                     GetDlgItemText(hDlg, SELECTED_DATABASE, dbName, MAX_DN_CHARS);
  267.                     SetDlgItemText(GetParent(hDlg), DATABASE_NAME, dbName);
  268.                     EndDialog (hDlg, 0);
  269.                     return TRUE;
  270.             }
  271.             break;
  272.     }
  273.     return FALSE;
  274. }
  275.  
  276.  
  277. /***************************************************************************
  278. **  Initializes all controls and variables for the Main Dialog.
  279. */
  280. WORD InitDialogStuff(HWND hDlg)
  281. {
  282.     NWDSCCODE      ccode;
  283.     DWORD              flags;
  284.     char                tmpContext[MAX_DN_CHARS];
  285.  
  286.     BWCCRegister(hInst);
  287.  
  288.     ccode = NWCallsInit(NULL, NULL);
  289.     if (ccode <0 )
  290.     {
  291.         HandleErrorMsg("InitDialogStuff", "NWCallsInit", ccode);
  292.         return(ccode);
  293.     }
  294.     gContext = NWDSCreateContext();
  295.     if(gContext == ERR_CONTEXT_CREATION)
  296.     {
  297.         return((WORD)gContext);
  298.     }
  299.  
  300.     ccode = NWDSGetContext(gContext, DCK_NAME_CONTEXT, (void *)tmpContext);
  301.     if(ccode < 0)
  302.     {
  303.         HandleErrorMsg("InitDialogStuff", "NWDSGetContext", ccode);
  304.         return(ccode);
  305.     }
  306.  
  307.     ccode = NWDSRemoveAllTypes(gContext, tmpContext, nContext);
  308.     if(ccode < 0)
  309.     {
  310.         HandleErrorMsg("InitDialogStuff", "NWDSRemoveAllTypes", ccode);
  311.         return(ccode);
  312.     }
  313.  
  314.     ccode = NWDSGetContext(gContext, DCK_FLAGS, &flags);
  315.     if(ccode < 0)
  316.     {
  317.         HandleErrorMsg("InitDialogStuff", "NWDSGetContext", ccode);
  318.         return(ccode);
  319.     }
  320.  
  321.     flags |= DCV_TYPELESS_NAMES;
  322.     flags &= ~DCV_CANONICALIZE_NAMES;
  323.     ccode = NWDSSetContext(gContext, DCK_FLAGS, &flags);
  324.     if(ccode < 0)
  325.     {
  326.         HandleErrorMsg("InitDialogStuff", "NWDSSetContext", ccode);
  327.         return(ccode);
  328.     }
  329.  
  330.     ReadStoredDatabaseName(hDlg);
  331.     SetDlgItemText(hDlg, DBSERVER_NAME, "");
  332.     SetDlgItemText(hDlg, NWSERVER_NAME, "");
  333.     SetDlgItemText(hDlg, STATUS_MSG, "Not Authenticated");
  334.     return(FALSE);
  335. }
  336.  
  337.  
  338. /***************************************************************************
  339. **  Attempts to read the stored Database name from the User object in the
  340. **    attribute "DBName".  If it is successful in reading the database name
  341. **    the "DATABASE_NAME" text box will be updated with the read name.
  342. */
  343. WORD ReadStoredDatabaseName(HWND hDlg)
  344. {
  345.     NWDS_ITERATION         iterHandle=-1L;
  346.     NWDS_BUFFER                *inBuf, *outBuf;
  347.     NWCOUNT                        totalAttrs, totalValues;
  348.     NWDSCCODE                    ccode;
  349.     NWSYNTAX_ID                syntaxID;
  350.     char                            name[MAX_DN_CHARS];                    /* never anything but "DBName" */
  351.     char                            databaseName[MAX_DN_CHARS];
  352.     char                            objectName[MAX_DN_CHARS];
  353.  
  354.     ccode = NWDSWhoAmI(gContext, objectName);
  355.     if(ccode < 0)
  356.     {
  357.         HandleErrorMsg("ReadStoredDatabaseName", "NWWhoAmI", ccode);
  358.         return(TRUE);
  359.     }
  360.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &inBuf);
  361.     if(ccode <0)
  362.     {
  363.         HandleErrorMsg("ReadStoredDatabaseName", "NWDSAllocBuf", ccode);
  364.         return(TRUE);
  365.     }
  366.     ccode = NWDSAllocBuf(MAX_DN_CHARS, &outBuf);
  367.     if(ccode <0)
  368.     {
  369.         HandleErrorMsg("ReadStoredDatabaseName", "NWDSAllocBuf", ccode);
  370.         NWDSFreeBuf(outBuf);
  371.         return(TRUE);
  372.     }
  373.     ccode = NWDSInitBuf(gContext,DSV_READ,inBuf);
  374.     if(ccode <0)
  375.     {
  376.         HandleErrorMsg("ReadStoredDatabaseName", "NWDSInitBuf", ccode);
  377.         NWDSFreeBuf(inBuf);
  378.         NWDSFreeBuf(outBuf);
  379.         return(TRUE);
  380.     }
  381.     ccode = NWDSPutAttrName(gContext,inBuf,"DBName");  /* We only want the */
  382.     if(ccode <0)                                               /* attribute "Host Server"    */
  383.     {
  384.         HandleErrorMsg("ReadStoredDatabaseName", "NWDSPutAttrName", ccode);
  385.         NWDSFreeBuf(inBuf);
  386.         NWDSFreeBuf(outBuf);
  387.         return(TRUE);
  388.     }
  389.     ccode = NWDSRead(gContext,
  390.                 objectName,           /* name of Object to read (IN)    */
  391.                 DS_ATTRIBUTE_VALUES,    /* read name and value (IN)       */
  392.                 FALSE,                                /* only attributes specified (IN) */
  393.                 inBuf,                                /* buffer holding "Host Server" (IN)      */
  394.                 &iterHandle,                    /* read until all values (OUT)    */
  395.                 outBuf);                            /* where the values go to(OUT)    */
  396.     if(ccode < 0)
  397.     {
  398.         NWDSFreeBuf(inBuf);
  399.         NWDSFreeBuf(outBuf);
  400.         return(TRUE);
  401.     }
  402.     ccode = NWDSGetAttrCount(gContext, outBuf, &totalAttrs);
  403.     if(ccode < 0)
  404.     {
  405.         HandleErrorMsg("ReadStoredDatabaseName", "NWDSGetAttrCount", ccode);
  406.         NWDSFreeBuf(inBuf);
  407.         NWDSFreeBuf(outBuf);
  408.         return(TRUE);
  409.     }
  410.     if((NWCOUNT)0 == totalAttrs)
  411.     {
  412.         NWDSFreeBuf(inBuf);
  413.         NWDSFreeBuf(outBuf);
  414.         return(TRUE);
  415.     }
  416.     else
  417.     {
  418.         ccode = NWDSGetAttrName(gContext,
  419.                                         outBuf,                        /* values are in here (IN)     */
  420.                                         name,                            /* better be DBName (OUT)         */
  421.                                         &totalValues,     /* number of values (OUT)      */
  422.                                         &syntaxID);                /* how to read the value (OUT) */
  423.  
  424.         if(ccode <0)
  425.         {
  426.             HandleErrorMsg("ReadStoredDatabaseName", "NWDSGetAttrName", ccode);
  427.             NWDSFreeBuf(inBuf);
  428.             NWDSFreeBuf(outBuf);
  429.             return(TRUE);
  430.         }
  431.         if(syntaxID != SYN_DIST_NAME)
  432.         {
  433.             MessageBox(NULL, "Syntax was wrong", "ReadStoredDatabaseName", MB_OK);
  434.             NWDSFreeBuf(inBuf);
  435.             NWDSFreeBuf(outBuf);
  436.             return(TRUE);
  437.         }
  438.         ccode = NWDSGetAttrVal(gContext,                    /* context handle (IN)   */
  439.                                     outBuf,                   /* buffer with info (IN) */
  440.                                     syntaxID,                 /* syntax ID (IN)        */
  441.                                     databaseName);            /* value of attrib (OUT) */
  442.         if(ccode <0)
  443.         {
  444.             HandleErrorMsg("ReadStoredDatabaseName", "NWDSGetAttrVal", ccode);
  445.             NWDSFreeBuf(inBuf);
  446.             NWDSFreeBuf(outBuf);
  447.             return(TRUE);
  448.         }
  449.     }
  450.  
  451.     if(databaseName)
  452.     {
  453.         SetDlgItemText(hDlg, DATABASE_NAME, databaseName);
  454.         return(FALSE);
  455.     }
  456.     else
  457.     {
  458.         SetDlgItemText(hDlg, DATABASE_NAME, "");
  459.         return(TRUE);
  460.     }
  461. }
  462.  
  463.  
  464. WORD SetStoredDatabaseName(HWND hDlg)
  465. {
  466.     NWDS_BUFFER                *inBuf;
  467.     NWDSCCODE                    ccode;
  468.     char                            databaseName[MAX_DN_CHARS];
  469.     char                            objectName[MAX_DN_CHARS];
  470.  
  471.     GetDlgItemText(hDlg, DATABASE_NAME, databaseName, MAX_DN_CHARS);
  472.  
  473.     ccode = NWDSWhoAmI(gContext, objectName);
  474.     if(ccode < 0)
  475.     {
  476.         HandleErrorMsg("SetStoredDatabaseName", "NWWhoAmI", ccode);
  477.         return(TRUE);
  478.     }
  479.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &inBuf);
  480.     if(ccode <0)
  481.     {
  482.         HandleErrorMsg("SetStoredDatabaseName", "NWDSAllocBuf", ccode);
  483.         return(TRUE);
  484.     }
  485.     ccode = NWDSInitBuf(gContext,DSV_MODIFY_ENTRY,inBuf);
  486.     if(ccode <0)
  487.     {
  488.         HandleErrorMsg("SetStoredDatabaseName", "NWDSInitBuf", ccode);
  489.         NWDSFreeBuf(inBuf);
  490.         return(TRUE);
  491.     }
  492.     ccode = NWDSPutChange(gContext, inBuf, DS_OVERWRITE_VALUE, "DBName");
  493.     if(ccode <0)
  494.     {
  495.         HandleErrorMsg("SetStoredDatabaseName", "NWDSPutChange", ccode);
  496.         NWDSFreeBuf(inBuf);
  497.         return(TRUE);
  498.     }
  499.     ccode = NWDSPutAttrVal(gContext, inBuf, SYN_DIST_NAME, databaseName);
  500.     if(ccode <0)
  501.     {
  502.         HandleErrorMsg("SetStoredDatabaseName", "NWDSPutAttrVal", ccode);
  503.         NWDSFreeBuf(inBuf);
  504.         return(TRUE);
  505.     }
  506.     ccode = NWDSModifyObject(gContext,
  507.                                                     objectName,
  508.                                                     NULL,
  509.                                                     (NWFLAGS)0,
  510.                                                     inBuf);
  511.     if(ccode < 0)
  512.     {
  513.         HandleErrorMsg("SetStoredDatabaseName", "NWDSModifyObject", ccode);
  514.         NWDSFreeBuf(inBuf);
  515.         return(TRUE);
  516.     }
  517.     return(FALSE);
  518. }
  519.  
  520.  
  521. /***************************************************************************
  522. **  Pops up the dialog and relates the process for the find database dialog.
  523. */
  524. WORD ShowDBFindDialog(HWND hDlg)
  525. {
  526.     static FARPROC lpfnDBFindDlgProc;
  527.     lpfnDBFindDlgProc = MakeProcInstance((FARPROC)DBFindDlgProc, hInst);
  528.     DialogBox(hInst, "DBFIND_DLG", GetActiveWindow(), lpfnDBFindDlgProc);
  529.     FreeProcInstance(lpfnDBFindDlgProc);
  530.  return FALSE;
  531. }
  532.  
  533.  
  534. /***************************************************************************
  535. **  Updates the find database dialog so the list of containers reflects the
  536. **  containers that are under the current context.  This is called any time
  537. **  a user changes the context in the browser.  (it is also called when first
  538. **    initialized.
  539. */
  540. WORD UpdateDBFindDialog(HWND hDlg)
  541. {
  542.     NWDS_BUFFER                    *outBuf;
  543.     NWDS_ITERATION                iterationHandle = -1L;
  544.     NWDSCCODE                    ccode;
  545.     NWCOUNT                        objectCount, attrCount,i;
  546.     NWOBJECT_INFO                objectInfo;
  547.     char                              objectName[MAX_DN_CHARS];
  548.  
  549.  
  550.     SendDlgItemMessage(hDlg, CONTAINER_LIST, LB_RESETCONTENT, 0, 0);
  551.     SendDlgItemMessage(hDlg, DATABASE_LIST, LB_RESETCONTENT, 0, 0);
  552.     SetDlgItemText(hDlg, CURRENT_CONTEXT, nContext);
  553.     SetDlgItemText(hDlg, SELECTED_DATABASE , "");
  554.  
  555.  
  556.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  557.     if(ccode < 0)
  558.     {
  559.         HandleErrorMsg("UpdateDBFindDialog", "NWDSAllocBuf", ccode);
  560.         return(TRUE);
  561.     }
  562.     do
  563.     {
  564.         ccode = NWDSList(gContext,
  565.                                     nContext,
  566.                                     &iterationHandle,
  567.                                     outBuf);
  568.         if(ccode < 0)
  569.         {
  570.             HandleErrorMsg("UpdateDBFindDialog", "NWDSList", ccode);
  571.             NWDSFreeBuf(outBuf);
  572.             return(TRUE);
  573.         }
  574.         ccode = NWDSGetObjectCount(gContext,
  575.                                             outBuf,
  576.                                             &objectCount);
  577.         if(ccode < 0)
  578.         {
  579.             HandleErrorMsg("UpdateDBFindDialog", "NWDSGetObjectCount", ccode);
  580.             NWDSFreeBuf(outBuf);
  581.             return(TRUE);
  582.         }
  583.         for(i=0; i<objectCount; i++)
  584.         {
  585.             ccode = NWDSGetObjectName(gContext,
  586.                                                 outBuf,
  587.                                                 objectName,
  588.                                                 &attrCount,
  589.                                                 &objectInfo);
  590.             if(ccode < 0)
  591.             {
  592.                 HandleErrorMsg("UpdateDBFindDialog", "NWDSGetObjectName", ccode);
  593.                 NWDSFreeBuf(outBuf);
  594.                 return(TRUE);
  595.             }
  596.             if(objectInfo.objectFlags & DS_CONTAINER_ENTRY)
  597.                 SendDlgItemMessage(hDlg, CONTAINER_LIST, LB_ADDSTRING, 0,
  598.                             (LONG) (LPSTR) objectName);
  599.             if(!strcmp(objectInfo.baseClass,"Database"))
  600.                 SendDlgItemMessage(hDlg, DATABASE_LIST, LB_ADDSTRING, 0,
  601.                             (LONG) (LPSTR) objectName);
  602.         }
  603.     }
  604.     while(iterationHandle != -1);
  605.     if(strcmp("[Root]", nContext))
  606.         SendDlgItemMessage(hDlg, CONTAINER_LIST, LB_ADDSTRING, 0,
  607.             (LONG) (LPSTR) "<- ..");
  608.     NWDSFreeBuf(outBuf);
  609.     return(FALSE);
  610. }
  611.  
  612.  
  613.  
  614. /***************************************************************************
  615. **  Changes the global context for the app when a new container is selected
  616. */
  617. WORD UpdateChangedContext(HWND hDlg)
  618. {
  619.     NWDSCCODE                    ccode;
  620.     char                            contextName[MAX_DN_CHARS];
  621.     char                            contextCName[MAX_DN_CHARS];
  622.     WORD                            n;
  623.  
  624.     n = (WORD) SendDlgItemMessage(hDlg, CONTAINER_LIST, LB_GETCURSEL, 0, 0L);
  625.     SendDlgItemMessage(hDlg, CONTAINER_LIST, LB_GETTEXT, n,
  626.                         (LONG) (LPSTR) contextName);
  627.  
  628.     if(!strcmp("<- ..", contextName))
  629.         strcpy(contextName, ".");
  630.  
  631.     ccode = NWDSCanonicalizeName(gContext, contextName, contextCName);
  632.     if(ccode < 0)
  633.     {
  634.         HandleErrorMsg("UpdateChangedContext", "NWDSCanonicalizeName", ccode);
  635.         return(ccode);
  636.     }
  637.     ccode = NWDSSetContext(gContext, DCK_NAME_CONTEXT, (void *)contextCName);
  638.     if(ccode < 0)
  639.     {
  640.         HandleErrorMsg("UpdateChangedContext", "NWDSSetContext", ccode);
  641.         return(ccode);
  642.     }
  643.     ccode = NWDSGetContext(gContext, DCK_NAME_CONTEXT, (void *)contextName);
  644.     if(ccode < 0)
  645.     {
  646.         HandleErrorMsg("UpdateChangedContext", "NWDSGetContext", ccode);
  647.         return(ccode);
  648.     }
  649.     ccode = NWDSRemoveAllTypes(gContext, contextName, nContext);
  650.     if(ccode < 0)
  651.     {
  652.         HandleErrorMsg("UpdateChangedContext", "NWDSRemoveAllTypes", ccode);
  653.         return(ccode);
  654.     }
  655.     return(FALSE);
  656. }
  657.  
  658.  
  659.  
  660. /***************************************************************************
  661. **  Updates the database field when a database is selected from the list.
  662. */
  663. WORD UpdateSelectedDatabase(HWND hDlg)
  664. {
  665.     char                            dbName[MAX_DN_CHARS];
  666.     char                            dbDName[MAX_DN_CHARS];
  667.     WORD                            n;
  668.  
  669.     n = (WORD) SendDlgItemMessage(hDlg, DATABASE_LIST, LB_GETCURSEL, 0, 0L);
  670.     SendDlgItemMessage(hDlg, DATABASE_LIST, LB_GETTEXT, n,
  671.                         (LONG) (LPSTR) dbName);
  672.     strcpy(dbDName, dbName);
  673.     strcat(dbDName, ".");
  674.     strcat(dbDName, nContext);
  675.     SetDlgItemText(hDlg, SELECTED_DATABASE, dbDName);
  676.     return(FALSE);
  677. }
  678.  
  679.  
  680. /***************************************************************************
  681. **  Main control for finding the Database Server (by reading the location
  682. **  from the database) and then the NetWare server than has the NLM loaded
  683. **  (by reading the location fromt the Database server.  Finally, the
  684. **  Network address of the NetWare server is found and the NCP Extention
  685. **  call is made.
  686. */
  687. WORD DoAuthentication(HWND hDlg)
  688. {
  689.     char                        dbName[MAX_DN_CHARS];
  690.     char                        dbServerName[MAX_DN_CHARS];
  691.     char                        nwServerName[MAX_DN_CHARS];
  692.  
  693.     GetDlgItemText(hDlg, DATABASE_NAME, dbName, MAX_DN_CHARS);
  694.     SetDlgItemText(hDlg, STATUS_MSG, "Looking up Database...");
  695.  
  696.     if(!GetHostServer(dbName, dbServerName))
  697.     {
  698.         if(!GetHostServer(dbServerName, nwServerName))
  699.         {
  700.             if(!GetConnectionHandle(nwServerName, &gConnHandle))
  701.             {
  702.                 if(!NWDSAuthenticate(gConnHandle, 0, NULL))
  703.                 {
  704.                     SetDlgItemText(hDlg, STATUS_MSG, "Making NCP Call...");
  705.                     if(!DoNCPCall(dbName, &gConnHandle))
  706.                     {
  707.                         SetDlgItemText(hDlg, STATUS_MSG, "Authenticated");
  708.                         SetDlgItemText(hDlg, DBSERVER_NAME, dbServerName);
  709.                         SetDlgItemText(hDlg, NWSERVER_NAME, nwServerName);
  710.                         EnableWindow(GetDlgItem(hDlg, IDC_UNAUTH_BUT), TRUE);
  711.                         EnableWindow(GetDlgItem(hDlg, IDC_AUTH_BUT), FALSE);
  712.                         EnableWindow(GetDlgItem(hDlg, IDC_LOCATE_BUT), FALSE);
  713.                         EnableWindow(GetDlgItem(hDlg, DATABASE_NAME), FALSE);
  714.                         return(FALSE);
  715.                     }
  716.                     else
  717.                         SetDlgItemText(hDlg, STATUS_MSG, "Not Authenticated");
  718.                 }
  719.             }
  720.         }
  721.     }
  722.     else
  723.     {
  724.         return(TRUE);
  725.     }
  726.     return(TRUE);
  727. }
  728.  
  729.  
  730. /***************************************************************************
  731. **  Resets the Dialog to reflect no authentication but doesn't have to do
  732. **  anything to the actuall server because we really didn't have a service
  733. **  loaded in this example.
  734. */
  735. WORD DoUnAuthentication(HWND hDlg)
  736. {
  737.     SetDlgItemText(hDlg, STATUS_MSG, "Not Authenticated");
  738.     SetDlgItemText(hDlg, DBSERVER_NAME, "");
  739.     SetDlgItemText(hDlg, NWSERVER_NAME, "");
  740.     EnableWindow(GetDlgItem(hDlg, IDC_UNAUTH_BUT), FALSE);
  741.     EnableWindow(GetDlgItem(hDlg, IDC_AUTH_BUT), TRUE);
  742.     EnableWindow(GetDlgItem(hDlg, IDC_LOCATE_BUT), TRUE);
  743.     EnableWindow(GetDlgItem(hDlg, DATABASE_NAME), TRUE);
  744.     return(FALSE);
  745. }
  746.  
  747.  
  748.  
  749. /***************************************************************************
  750. **  Reads the host server object name from the object name passed in.
  751. **  Both the Database and Database Servers have host servers.  The host
  752. **  server for a Database is a Database Server and the host server for
  753. **  a Database Server is a NetWare Server.
  754. */
  755. WORD GetHostServer(char *objectName, char *hostServer)
  756. {
  757.     NWDS_ITERATION         iterHandle=-1L;
  758.     NWDS_BUFFER                *inBuf, *outBuf;
  759.     NWCOUNT                    totalAttrs, totalValues;
  760.     NWDSCCODE                ccode;
  761.     NWSYNTAX_ID                syntaxID;
  762.     char                        name[MAX_DN_CHARS];                    /* never anything but "Host Server" */
  763.     char                        tmpHostServer[MAX_DN_CHARS];
  764.  
  765.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &inBuf);
  766.     if(ccode <0)
  767.     {
  768.         HandleErrorMsg("GetHostServer", "NWDSAllocBuf", ccode);
  769.         return(TRUE);
  770.     }
  771.     ccode = NWDSAllocBuf(MAX_DN_CHARS, &outBuf);
  772.     if(ccode <0)
  773.     {
  774.         HandleErrorMsg("GetHostServer", "NWDSAllocBuf", ccode);
  775.         NWDSFreeBuf(outBuf);
  776.         return(TRUE);
  777.     }
  778.     ccode = NWDSInitBuf(gContext,DSV_READ,inBuf);
  779.     if(ccode <0)
  780.     {
  781.         HandleErrorMsg("GetHostServer", "NWDSInitBuf", ccode);
  782.         NWDSFreeBuf(inBuf);
  783.         NWDSFreeBuf(outBuf);
  784.         return(TRUE);
  785.     }
  786.     ccode = NWDSPutAttrName(gContext,inBuf,"Host Server");  /* We only want the */
  787.     if(ccode <0)                                               /* attribute "Host Server"    */
  788.     {
  789.         HandleErrorMsg("GetHostServer", "NWDSPutAttrName", ccode);
  790.         NWDSFreeBuf(inBuf);
  791.         NWDSFreeBuf(outBuf);
  792.         return(TRUE);
  793.     }
  794.     ccode = NWDSRead(gContext,
  795.                 objectName,           /* name of Object to read (IN)    */
  796.                 DS_ATTRIBUTE_VALUES,    /* read name and value (IN)       */
  797.                 FALSE,                                /* only attributes specified (IN) */
  798.                 inBuf,                                /* buffer holding "Host Server" (IN)      */
  799.                 &iterHandle,                    /* read until all values (OUT)    */
  800.                 outBuf);                            /* where the values go to(OUT)    */
  801.     if(ccode < 0)
  802.     {
  803.         HandleErrorMsg("GetHostServer", "NWDSRead", ccode);
  804.         NWDSFreeBuf(inBuf);
  805.         NWDSFreeBuf(outBuf);
  806.         return(TRUE);
  807.     }
  808.     ccode = NWDSGetAttrCount(gContext, outBuf, &totalAttrs);
  809.     if(ccode < 0)
  810.     {
  811.         HandleErrorMsg("GetHostServer", "NWDSGetAttrCount", ccode);
  812.         NWDSFreeBuf(inBuf);
  813.         NWDSFreeBuf(outBuf);
  814.         return(TRUE);
  815.     }
  816.     if((NWCOUNT)0 == totalAttrs)
  817.     {
  818.         MessageBox(NULL, "No Host Server was Found", "GetHostServer", MB_OK);
  819.         NWDSFreeBuf(inBuf);
  820.         NWDSFreeBuf(outBuf);
  821.         return(TRUE);
  822.     }
  823.     else
  824.     {
  825.         ccode = NWDSGetAttrName(gContext,
  826.                                         outBuf,                        /* values are in here (IN)     */
  827.                                         name,                            /* better be Host Server (OUT)         */
  828.                                         &totalValues,     /* number of values (OUT)      */
  829.                                         &syntaxID);                /* how to read the value (OUT) */
  830.  
  831.         if(ccode <0)
  832.         {
  833.             HandleErrorMsg("GetHostServer", "NWDSGetAttrName", ccode);
  834.             NWDSFreeBuf(inBuf);
  835.             NWDSFreeBuf(outBuf);
  836.             return(TRUE);
  837.         }
  838.         if(syntaxID != SYN_DIST_NAME)
  839.         {
  840.             MessageBox(NULL, "Syntax was wrong", "GetHostServer", MB_OK);
  841.             NWDSFreeBuf(inBuf);
  842.             NWDSFreeBuf(outBuf);
  843.             return(TRUE);
  844.         }
  845.         ccode = NWDSGetAttrVal(gContext,                    /* context handle (IN)   */
  846.                                     outBuf,                   /* buffer with info (IN) */
  847.                                     syntaxID,                 /* syntax ID (IN)        */
  848.                                     tmpHostServer);                     /* value of attrib (OUT) */
  849.         if(ccode <0)
  850.         {
  851.             HandleErrorMsg("GetHostServer", "NWDSGetAttrVal", ccode);
  852.             NWDSFreeBuf(inBuf);
  853.             NWDSFreeBuf(outBuf);
  854.             return(TRUE);
  855.         }
  856.     }
  857.  
  858.     if(tmpHostServer)
  859.     {
  860.         strcpy(hostServer,tmpHostServer);
  861.         return(FALSE);
  862.     }
  863.     else
  864.     {
  865.         strcpy(hostServer, NULL);
  866.         return(TRUE);
  867.     }
  868. }
  869.  
  870.  
  871. /***************************************************************************
  872. **  Creates (if not already connected) and reads the connection handle from
  873. **  the passed in NetWare server.
  874. */
  875. WORD GetConnectionHandle(char *nwServerName, NWCONN_HANDLE NWFAR *connHandle)
  876. {
  877.     NWDS_BUFFER                    *outBuf,*inBuf;
  878.     NWDS_ITERATION                iterationHandle = -1L;
  879.     NWDSCCODE                    ccode;
  880.     NWSIZE                        attrSize;
  881.     void                            *attrValue;
  882.     NWSYNTAX_ID                    syntax;
  883.     NWCOUNT                        valCount;
  884.     NWCOUNT                        totalAttrs;
  885.     char                            currAttr[MAX_DN_CHARS];
  886.  
  887.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &inBuf);
  888.     if(ccode < 0)
  889.         return(ccode);
  890.     ccode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &outBuf);
  891.     if(ccode < 0)
  892.     {
  893.             NWDSFreeBuf(inBuf);
  894.             return(ccode);
  895.      }
  896.     ccode = NWDSInitBuf(gContext,DSV_READ,inBuf);
  897.     if(ccode <0)
  898.     {
  899.             NWDSFreeBuf(inBuf);
  900.             NWDSFreeBuf(outBuf);
  901.             return(ccode);
  902.     }
  903.     ccode = NWDSPutAttrName(gContext,inBuf,"Network Address");
  904.     if(ccode <0)
  905.     {
  906.             NWDSFreeBuf(inBuf);
  907.             NWDSFreeBuf(outBuf);
  908.             return(ccode);
  909.     }
  910.  
  911.     ccode = NWDSRead(gContext,                    /* Context Handle  (IN)        */
  912.                             nwServerName,            /* name of object  (IN)        */
  913.                             DS_ATTRIBUTE_VALUES,        /* a #define         (IN)            */
  914.                             FALSE,                            /* #define as 1 (IN)            */
  915.                             inBuf,                            /* Attribute names (IN)     */
  916.                             &iterationHandle,            /* iteration Handle (OUT) */
  917.                             outBuf);                  /* Output Buffer (OUT)         */
  918.     if(ccode < 0)
  919.     {
  920.             NWDSFreeBuf(inBuf);
  921.             NWDSFreeBuf(outBuf);
  922.             return(ccode);
  923.     }
  924.     ccode = NWDSGetAttrCount(gContext, outBuf, &totalAttrs);
  925.     if(ccode < 0)
  926.     {
  927.             NWDSFreeBuf(inBuf);
  928.             NWDSFreeBuf(outBuf);
  929.             return(ccode);
  930.     }
  931.     if((NWCOUNT)0 == totalAttrs)
  932.     {
  933.             NWDSFreeBuf(inBuf);
  934.             NWDSFreeBuf(outBuf);
  935.             return(TRUE);
  936.     }
  937.     else
  938.     {
  939.         ccode = NWDSGetAttrName(gContext, outBuf, currAttr, &valCount, &syntax);
  940.         if(ccode < 0)
  941.         {
  942.                 NWDSFreeBuf(inBuf);
  943.                 NWDSFreeBuf(outBuf);
  944.                 return(ccode);
  945.         }
  946.  
  947.         ccode = NWDSComputeAttrValSize(gContext, outBuf, syntax, &attrSize);
  948.         if(ccode < 0)
  949.         {
  950.                 NWDSFreeBuf(inBuf);
  951.                 NWDSFreeBuf(outBuf);
  952.                 return(ccode);
  953.         }
  954.         attrValue=malloc((size_t)attrSize);
  955.         if(attrValue == NULL)
  956.         {
  957.                 NWDSFreeBuf(inBuf);
  958.                 NWDSFreeBuf(outBuf);
  959.                 return(ccode);
  960.         }
  961.         memset(attrValue, '\x0', (size_t)attrSize);
  962.         ccode = NWDSGetAttrVal(gContext, outBuf, syntax, attrValue);
  963.         if(ccode < 0)
  964.         {
  965.                 NWDSFreeBuf(inBuf);
  966.                 NWDSFreeBuf(outBuf);
  967.                 return(ccode);
  968.         }
  969.         ccode = NWDSGetConnectionSlot(1,
  970.                                     ((Net_Address_T *)attrValue)->addressType,
  971.                                     ((Net_Address_T *)attrValue)->addressLength,
  972.                                     ((Net_Address_T *)attrValue)->address,
  973.                                     connHandle);
  974.         if(ccode < 0)
  975.         {
  976.             NWDSFreeBuf(inBuf);
  977.             NWDSFreeBuf(outBuf);
  978.             return(ccode);
  979.         }
  980.         free(attrValue);
  981.     }
  982.     NWDSFreeBuf(inBuf);
  983.     NWDSFreeBuf(outBuf);
  984.     return(ccode);
  985. }
  986.  
  987.  
  988. /***************************************************************************
  989. **  Actually makes the NCP Extention call.
  990. */
  991. WORD DoNCPCall(char *dbName, NWCONN_HANDLE NWFAR *connHandle)
  992. {
  993.     NWDSCCODE         ccode;
  994.     DWORD                NCPExtID;
  995.     BYTE                majorVersion;
  996.     BYTE                minorVersion;
  997.     BYTE                revision;
  998.     BYTE                queryData[32];
  999.     AUTHREQUEST        Request;
  1000.     AUTHREPLY         Reply;
  1001.     WORD                replyLen;
  1002.  
  1003.     /* Make sure NCP Extension server is loaded */
  1004.  
  1005.     ccode = NWGetNCPExtensionInfoByName(*connHandle, NCPEXTNAME, &NCPExtID,
  1006.         &majorVersion, &minorVersion, &revision, queryData);
  1007.     if (ccode < 0)
  1008.     {
  1009.         HandleErrorMsg("DoNCPCall", "NWGetNCPExtensionInfoByName", ccode);
  1010.         return(TRUE);
  1011.     }
  1012.  
  1013.     /* Setup AUTHREQUEST block for NCPExtension request */
  1014.  
  1015.     Request.Command = DO_AUTH;
  1016.  
  1017.     /* Check command line arguments */
  1018.  
  1019.     strcpy(Request.objectName, dbName);
  1020.     replyLen = sizeof(AUTHREPLY);
  1021.  
  1022.     ccode = NWNCPExtensionRequest(*connHandle, NCPExtID,
  1023.         &Request, sizeof(AUTHREQUEST), &Reply, &replyLen);
  1024.     if (ccode < 0)
  1025.     {
  1026.         HandleErrorMsg("DoNCPCall", "NWNCPExtensionRequest", ccode);
  1027.         return(TRUE);
  1028.     }
  1029.     if (Reply.completionCode != SUCCESSFUL)
  1030.     {
  1031.         MessageBox(NULL, "Authentication Failed from NCP", "DoNCPCall", MB_OK);
  1032.         return(TRUE);
  1033.     }
  1034.     return(FALSE);
  1035. }
  1036.  
  1037.  
  1038.  
  1039. /***************************************************************************
  1040. **  A procedure for handling all error messages.
  1041. */
  1042. WORD HandleErrorMsg(char *funcName, char *message, NWDSCCODE ccode)
  1043. {
  1044.     char    newMessage[DEFAULT_MESSAGE_LEN];
  1045.  
  1046.     wsprintf(newMessage,"The Function: %s\n making the call: %s\n returned code: %d",funcName, message, ccode);
  1047.     MessageBox(NULL, newMessage, "NDSError", MB_OK);
  1048.     return(FALSE);
  1049. }
  1050.  
  1051.