/********************************************************************

   Copyright (c) 1996 Novell, Inc.  All Rights Reserved.

   With respect to this file, Novell hereby grants to Developer a 
   royalty-free, non-exclusive license to include this sample code 
   and derivative binaries in its product. Novell grants to Developer 
   worldwide distribution rights to market, distribute or sell this 
   sample code file and derivative binaries as a component of 
   Developer's product(s).  Novell shall have no obligations to 
   Developer or Developer's customers with respect to this code.

   DISCLAIMER:

   Novell disclaims and excludes any and all express, implied, and 
   statutory warranties, including, without limitation, warranties 
   of good title, warranties against infringement, and the implied 
   warranties of merchantability and fitness for a particular purpose.  
   Novell does not warrant that the software will satisfy customer's 
   requirements or that the licensed works are without defect or error 
   or that the operation of the software will be uninterrupted.  
   Novell makes no warranties respecting any technical services or 
   support tools provided under the agreement, and disclaims all other 
   warranties, including the implied warranties of merchantability and 
   fitness for a particular purpose. */

/*********************************************************************
   NDSADD1.C
**********************************************************************

   Description:
   
   Add a User object with the name, surname and telephone
   number entered by user.  The input buffer is initialized
   for an ADD_ENTRY operation in the NWDSInitBuf call.
   NWDSPutAttrName and NWDSPutAttrVal place the
   attribute names and associated values into the input buffer
   before NWDSAddObject is called.

   This example requires that you login as SUPERVISOR (if you
   haven't authenticated to NDS before running the example, the
   program will prompt for user input and perform the 
   authentication).  Also, at the Enter user name prompt, a 
   valid object name must be entered 
   (for example, .CN=myname.OU=myunit.O=myorg) 

*********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <nwnet.h>
#include <nwcalls.h>
#include <nwlocale.h>

/* cleanup functions and globals */
void   FreeBuf(pBuf_T pBuf, NWDSContextHandle context);
void   FreeContext(NWDSContextHandle context);     
void   FreeUnicodeTables();
nbool8 bbDoLogout = N_FALSE;

void main(void)
{
   NWDSContextHandle   context;
   pBuf_T              pBuf;
   NWCCODE             ccode;
   NWDSCCODE           dsccode;
   nstr8               strUserName[NW_MAX_USER_NAME_LEN];
   nstr8               strUserPassword[50];
   nstr8               strObjectName[MAX_DN_CHARS+1];
   nstr8               strSurname[MAX_DN_CHARS+1];
   nstr8               strPhone[14];
   LCONV               lConvInfo;

   /*  Initialize NWCalls and unicode tables */
   ccode = NWCallsInit(NULL,NULL);
   if(ccode)
   {
      printf("\nNWCallsInit returned %X", ccode);
      exit(1);
   }

   NWLlocaleconv(&lConvInfo);

   ccode = NWInitUnicodeTables(lConvInfo.country_id,
                               lConvInfo.code_page);
   if(ccode)
   {
      printf("\nNWInitUnicodeTables error %X \n", ccode);
      exit(1);
   }

   /* Create an NDS Context */
   ccode = NWDSCreateContextHandle(&context);
   if(ccode)
   {
      printf("\nNWDSCreateContextHandle failed");
      FreeUnicodeTables();
   }

   /*  Must authenticate if not already authenticated to NDS
       (which will always be the case if this example is 
       compiled and run as an NLM).  Creating an NDS object
       requires SUPERVISOR rights. */
   if(!NWIsDSAuthenticated())
   {
      printf("\nMust authenticate to NDS");
      printf("\nEnter User Name: ");
      gets(strUserName);
      printf("Enter User Password: ");
      gets(strUserPassword);

      dsccode = NWDSLogin(context, 0, strUserName, strUserPassword, 0);
      if(dsccode)
      {
         printf("\nNWDSLogin returned %X", dsccode);
         FreeContext(context);
      }
      else
      {  /* If example logs in, it will also log out */
         bbDoLogout = N_TRUE;
      }
   }

   /*  Prompt for information about object to create */
   printf("\nEnter information about object to create");
   printf("\nEnter user name");
   printf("\n(example: .CN=myname.OU=myunit.O=myorg): ");
   gets(strObjectName);
   printf("\nEnter surname: ");
   gets(strSurname);
   printf("\nEnter telephone number: ");
   gets(strPhone);

   /*  Create the input buffer */
   dsccode = NWDSAllocBuf((size_t)DEFAULT_MESSAGE_LEN, &pBuf);
   if(dsccode)
   {
      printf("\nNWDSAllocBuf returned %X", dsccode);
      FreeContext(context);
   }

   /* Initialize buffer for Directory Services ADD operation */
   dsccode = NWDSInitBuf(context, DSV_ADD_ENTRY, pBuf);
   if(dsccode)
   {
      printf("\nNWDSInitBuf returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   /* Call NWDSPutAttrName and NWDSPutAttrVal repeatedly for each type
      of information about to be entered.  Start with User
      (Object Class).  */
   dsccode = NWDSPutAttrName(context, pBuf, "Object Class");
   if(dsccode)
   {
      printf("\nNWDSPutAttrName returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   /* The data type SYN_CLASS_NAME corresponds to User */
   dsccode = NWDSPutAttrVal(context, pBuf, SYN_CLASS_NAME, "User");
   if(dsccode)
   {
      printf("\nNWDSPutAttrVal returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   /* Add information for Surname */
   dsccode = NWDSPutAttrName(context, pBuf, "Surname");
   if(dsccode)
   {
      printf("\nNWDSPutAttrName returned %X", dsccode);
      FreeBuf(pBuf, context);
   }
   
   /* The data type SYN_CI_STRING corresponds to surname */
   dsccode = NWDSPutAttrVal(context, pBuf, SYN_CI_STRING, strSurname);
   if(dsccode)
   {
      printf("\nNWDSPutAttrVal returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   /* Add information for Telephone Number */
   dsccode = NWDSPutAttrName(context, pBuf, "Telephone Number");
   if(dsccode)
   {
      printf("\nNWDSPutAttrName returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   dsccode = NWDSPutAttrVal(context, pBuf, SYN_TEL_NUMBER, strPhone);
   if(dsccode)
   {
      printf("\nNWDSPutAttrVal returned %X", dsccode);
      FreeBuf(pBuf, context);
   }

   printf("\nCreating user %s %s with telephone %s.\n",
            strObjectName, strSurname, strPhone);

   /*  NWDSAddObject creates the object pointed to by
       strObjectName. The 3rd and 4th args are reserved
       (NULL and 0 here).  */
   dsccode = NWDSAddObject(context, strObjectName, NULL, 0, pBuf);
   if(dsccode)
   {
      printf("\nNWDSAddObject returned %i", dsccode);
      printf("\nUnable to create user");
   }
   else
      printf("\nUser %s has been added to NDS.", strObjectName);

   /* Clean up, normal termination */
   NWDSFreeBuf(pBuf);
   if(bbDoLogout)
      NWDSLogout(context);
   NWDSFreeContext(context);
   NWFreeUnicodeTables();
}

/* Clean up and exit, called on error condition only */
void FreeBuf(pBuf_T pBuf, NWDSContextHandle context)
{
   NWDSFreeBuf(pBuf);
   FreeContext(context);
}

void FreeContext(NWDSContextHandle context)
{
   if(bbDoLogout)
      NWDSLogout(context);
   NWDSFreeContext(context);
   FreeUnicodeTables();
}

void FreeUnicodeTables()
{
   NWFreeUnicodeTables();
   exit(1);
}  

