From 38a2bc61a1034fc76aa6cb1612af7b9f1b9e62ba Mon Sep 17 00:00:00 2001
From: Jim Norman <jnorman@novell.com>
Date: Wed, 16 May 2007 23:07:25 +0000
Subject: [PATCH] Bug 265898. Replace mono based cli with native based one.
 This was needed to support changing the UID

---
 CASA/CASA.changes               |   6 +
 CASA/Makefile.am                |   8 +-
 CASA/cli/Makefile.am            | 236 +++++++------
 CASA/cli/casacli.c              | 606 ++++++++++++++++++++++++++++++++
 CASA/micasadk/sscs_ndk.c        |  10 +-
 CASA/package/linux/CASA.spec.in |   4 +-
 6 files changed, 742 insertions(+), 128 deletions(-)
 create mode 100644 CASA/cli/casacli.c

diff --git a/CASA/CASA.changes b/CASA/CASA.changes
index 444ef7f1..f1cae2d2 100644
--- a/CASA/CASA.changes
+++ b/CASA/CASA.changes
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Wed May 16 17:01:03 MDT 2007 - jnorman@novell.com
+
+- Bug 265898. Replace mono based cli with native based one. 
+  This was needed to support changing the UID  
+
 -------------------------------------------------------------------
 Fri May 11 10:09:25 MDT 2007 - jnorman@novell.com
 
diff --git a/CASA/Makefile.am b/CASA/Makefile.am
index 8e70abd3..6f74e07f 100644
--- a/CASA/Makefile.am
+++ b/CASA/Makefile.am
@@ -26,10 +26,10 @@ TARGET_CFG = Release
 endif
 
 if LINUX
-SUBDIRS = micasacache common micasadk micasad/lib sharp cli  \
-	policy adlib micasad gui logincapture jwrapper package
+SUBDIRS = micasacache common micasadk micasad/lib sharp  \
+	policy adlib micasad cli gui logincapture jwrapper package
 
-DIST_SUBDIRS = micasacache common micasadk micasad sharp cli \
+DIST_SUBDIRS = micasacache common micasadk micasad cli sharp \
 	policy adlib gui logincapture jwrapper package
 endif
 
@@ -38,7 +38,7 @@ SUBDIRS = package
 DIST_SUBDIRS = micasacache common micasadk jwrapper  package
 endif
 
-EXTRA_DIST = include include/*.h  cli/* \
+EXTRA_DIST = include include/*.h  \
 	     doc/internal/*.doc doc/internal/*.xsd \
              doc/product/*.pdf doc/product/*.txt \
 	     readme-folder/readme*  autogen.sh 
diff --git a/CASA/cli/Makefile.am b/CASA/cli/Makefile.am
index 3530af82..99d1522a 100644
--- a/CASA/cli/Makefile.am
+++ b/CASA/cli/Makefile.am
@@ -1,117 +1,119 @@
-#######################################################################
-#
-#  Copyright (C) 2006 Novell, Inc.
-#
-#  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.
-#
-#
-#######################################################################
-
-if DEBUG
-TARGET_CFG = Debug
-CFLAGS += -v -w
-CS_EXTRA_FLAGS = $(CSCFLAGS_DEBUG)  
-else
-TARGET_CFG = Release
-endif
-
-SUBDIRS =
-DIST_SUBDIRS =  
-
-EXTRA_DIST = $(CSFILES) CASAcli* CASAUtil* 
-
-#EXTRA_DIST = $(CSFILES) help/en  help/en/*.htm  help/en/*.gif \
-#	     images/*.png images/*.ico images/*.glade* \
-#	     images/*.bmp 
-
-CASAROOT = ..
-
-CASALIBDIR = $(CASAROOT)/$(LIB)/$(TARGET_CFG)
-
-if LIB64 
-CASABINDIR = $(CASAROOT)/bin64
-else
-CASABINDIR = $(CASAROOT)/bin
-endif
-
-# handle Mono secondary dependencies
-export MONO_PATH := $(MONO_PATH)
-
-PLATFORMINDEPENDENTSOURCEDIR =
-PLATFORMDEPENDENTSOURCEDIR = .
-
-MODULE_NAME =CASAcli
-MODULE_EXT =exe
-
-CSFILES =$(srcdir)/CASAUtil.cs 
-
-CSFILES_CSC := $(subst /,$(SEP),$(CSFILES))
-CS_FLAGS = -d:LINUX -nowarn:169 
-CS_RESOURCES =
-CS_LIBS = $(CASALIBDIR)/Novell.CASA.miCASAWrapper.dll
-
-CS_LIBPATH = ../c_micasad/test/dependencies  \
-	$(CASALIBDIR) 
-
-OBJDIR = ./$(TARGET_CFG)/$(LIB)
-
-#OBJS = $(addprefix $(OBJDIR)/, $(CSFILES:%.dll=%.cs))
-
-CUR_DIR := $(shell pwd)
-
-all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
-
-#
-# Pattern based rules.
-#
-vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
-vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
-vpath %.cs $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
-
-$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(CSFILES) 
-	$(CSC) $(CS_FLAGS) $(CS_EXTRA_FLAGS) $(CS_LIBPATH:%=-lib:%) $(CS_LIBS:%=/r:%) -out:$@ $(CSFILES_CSC) 
-	cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(CASABINDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
-
-#$(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT): $(OBJDIR) $(OBJS)
-#	@echo [======== Linking $@ ========]
-#	$(LINK) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
-#	cp -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(CASALIBDIR)/$(TARGET_CFG)/$(MODULE_NAME).$(MODULE_EXT)
-
-$(OBJDIR):
-	[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
-	[ -d $(CASABINDIR) ] || mkdir -p $(CASABINDIR)
-	[ -d $(CASABINDIR)/$(TARGET_CFG) ] || mkdir -p $(CASABINDIR)/$(TARGET_CFG)
-
-
-install-exec-local: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
-	$(mkinstalldirs) $(DESTDIR)$(libdir)
-	$(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT) $(DESTDIR)$(libdir)/
-
-uninstall-local:
-	cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT)
-	rmdir $(DESTDIR)$(libdir)
-
-#installcheck-local: install
-#	$(mkinstalldirs) $(DESTDIR)$(libdir)
-#	$(INSTALL_PROGRAM) $(DESTDIR)$(libdir)
-#	cd $(DESTDIR)$(libdir); $(MONO)
-
-clean-local:
-	if [ -d $(TARGET_CFG) ]; then  rm -rf $(TARGET_CFG); fi
-
-distclean-local:
-
-maintainer-clean-local:
-	rm -f Makefile.in
+#######################################################################
+#
+#  Copyright (C) 2006 Novell, Inc.
+#
+#  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.
+#
+#
+#######################################################################
+
+if DEBUG
+TARGET_CFG = Debug
+CFLAGS += -v -w
+else
+TARGET_CFG = Release
+endif
+
+SUBDIRS =
+DIST_SUBDIRS =
+
+EXTRA_DIST = $(CFILES)
+
+CASAROOT = ..
+
+CASALIBDIR = $(CASAROOT)/$(LIB)
+
+if LIB64
+CASABINDIR = $(CASAROOT)/bin64
+else
+CASABINDIR = $(CASAROOT)/bin
+endif
+
+
+OBJDIR = $(TARGET_CFG)/$(LIB)
+
+BUILD_VER = 1.1.1
+
+# handle Mono secondary dependencies
+export MONO_PATH := $(MONO_PATH)
+
+PLATFORMINDEPENDENTSOURCEDIR = ..
+PLATFORMDEPENDENTSOURCEDIR = .
+
+MODULE_NAME = CASAcli
+MODULE_EXT =
+
+CFILES = casacli.c 
+
+CSFILES_CSC :=
+INCLUDES = -I. -I.. -I$(CASAROOT)/include 
+EXTRA_CFLAGS = 
+RESOURCES =
+CFLAGS += $(EXTRA_CFLAGS) $(INCLUDES) $(DEFINES)
+LIBS = -L/$(CASALIBDIR)/$(TARGET_CFG)  
+
+LDFLAGS = -lmicasa 
+
+OBJS = $(addprefix $(OBJDIR)/, $(CFILES:%.c=%.o))
+#COMMON_OBJS = -L/../../c_common/linux/$(OBJDIR) ../../c_common/linux/$(OBJDIR)/sscs_ll.o 
+COMMON_OBJS = $(OBJDIR)/sscs_ll.o 
+CUR_DIR := $(shell pwd)
+
+#all: $(OBJDIR)/$(MODULE_NAME).$(MODULE_EXT).$(BUILD_VER)
+all: $(OBJDIR)/$(MODULE_NAME)
+
+#
+# Pattern based rules.
+#
+vpath %.c $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
+vpath %.cpp $(PLATFORMDEPENDENTSOURCEDIR) $(PLATFORMINDEPENDENTSOURCEDIR)
+
+$(OBJDIR)/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/%.o: %.cpp
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+$(OBJDIR)/$(MODULE_NAME): $(OBJDIR) $(OBJS)
+	@echo [======== Linking $@ ========]
+	cc $(LDFLAGS) -o $@ $(OBJS) $(LIBS) 
+	cp -f $(OBJDIR)/$(MODULE_NAME) $(CASABINDIR)/$(TARGET_CFG)/$(MODULE_NAME)
+$(OBJDIR):
+	[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
+	[ -d $(CASALIBDIR) ] || mkdir -p $(CASALIBDIR)
+	[ -d $(CASALIBDIR)/$(TARGET_CFG) ] || mkdir -p $(CASALIBDIR)/$(TARGET_CFG)
+
+
+install-exec-local: $(OBJDIR)/$(MODULE_NAME)
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) $(OBJDIR)/$(MODULE_NAME) $(DESTDIR)$(libdir)/
+
+uninstall-local:
+	cd $(DESTDIR)$(libdir); rm -f $(OBJDIR)/$(MODULE_NAME)
+	rmdir $(DESTDIR)$(libdir)
+
+#installcheck-local: install
+#	$(mkinstalldirs) $(DESTDIR)$(libdir)
+#	$(INSTALL_PROGRAM) $(DESTDIR)$(libdir)
+#	cd $(DESTDIR)$(libdir); $(MONO)
+
+clean-local:
+	if [ -d $(TARGET_CFG) ]; then  rm -rf $(TARGET_CFG); fi
+
+distclean-local:
+
+maintainer-clean-local:
+	rm -f Makefile.in
+
diff --git a/CASA/cli/casacli.c b/CASA/cli/casacli.c
new file mode 100644
index 00000000..1fe5f49c
--- /dev/null
+++ b/CASA/cli/casacli.c
@@ -0,0 +1,606 @@
+/***********************************************************************
+ * 
+ *  Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; version 2.1
+ *  of the License.
+ *
+ *  This library 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
+ *  Library Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, Novell, Inc.
+ * 
+ *  To contact Novell about this file by physical or electronic mail, 
+ *  you may find current contact information at www.novell.com.
+ * 
+ ***********************************************************************/
+
+
+/* Sample code for C Language miCASA APIs */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+#include <conio.h>
+#include <windows.h>
+#else
+#define getch(x) getchar(x);
+#endif
+
+#include <string.h>
+#include <sscs_utf8.h>
+#include <micasa.h>
+#include <sscs_cache.h>
+
+
+/*
+ * Global data
+ */
+int		optErr = 1;			// if error message should be printed
+int   	optIdx = 1;	   		// index into parent argv vector
+int   	optionString = 1;	// character checked for validity
+char 	*optArg = NULL;		// argument associated with option
+char	*credName = NULL;
+char	*value = NULL;
+char	*keyName = NULL;
+char	*uid = NULL;
+
+int		iAction = 0;
+
+
+#define BADCHAR 	(int)'?'
+#define ERRMSG  	""
+#define SETCRED		1
+#define GETCRED		2
+#define DELCRED		3
+#define LISTCREDS	4
+
+///////////////////////////////////////////////////////////////////////
+
+
+
+void Pause()
+{ 
+	printf("\nPress a key ==>\n");
+	getch();
+} /* end of Pause */
+
+
+void CloseStore(void *context)
+{
+	miCASACloseSecretStoreCache(context, 0, NULL);
+}
+
+void* OpenStore(SSCS_KEYCHAIN_ID_T *kc)
+{
+	SSCS_SECRETSTORE_T 			store = {0};
+	void *context = 0;
+
+	// open secretStore
+	sscs_Utf8Strcpy(store.ssName, SSCS_DEFAULT_SECRETSTORE_ID);
+	store.version = 1;
+	context = miCASAOpenSecretStoreCache(&store, 0, NULL);
+
+	if (context == NULL)
+	{
+		printf("Could not open miCASA store\r\n");
+		return NULL; // NSSCS_E_SYSTEM_FAILURE;
+	}
+
+	sscs_Utf8Strcpy(kc->keychainID, SSCS_SERVER_KEY_CHAIN_ID);
+	kc->len = SSCS_S_KC_ID_SERVER_CHARS;
+
+	return context;
+
+}
+
+#ifdef LINUX
+void SetUID(int targetUID)
+{
+	int uid = geteuid();
+	int rcode = 0;
+	printf("Current uid: %d\r\n", uid);
+	
+	rcode = seteuid(targetUID);
+	if (rcode == -1)
+	{
+		printf("You do not have sufficient rights to set the uid\r\n");
+		exit(-1);
+	}
+	
+	uid = geteuid();
+	printf("uid is now: %d\r\n", uid);	
+		
+}
+
+void ResetUID()
+{
+	int rcode = seteuid(0);
+	printf("Reset rcode= %d", rcode);
+	printf("uid %d\r\n", getuid());
+}
+#endif
+void DisplaySecretEx(void *context, 
+					SSCS_KEYCHAIN_ID_T 	*kc, 
+					SSCS_SH_SECRET_ID_T *secretID)
+{
+	int rcode = 0;
+	void *secHandle;
+
+	int32_t start = 1;
+
+	int32_t keyLen = NSSCS_MAX_ID_LEN;
+	SS_UTF8_T key[NSSCS_MAX_ID_LEN] = {0};
+	int32_t valLen = 512;
+	uint8_t value[512] = {0};
+	
+	secHandle = miCASA_CreateSHSHandle();
+
+	rcode = miCASAReadSecret(context, 
+							kc,
+							0,
+							secHandle,
+							secretID,
+							NULL,
+							NULL,
+							NULL);
+
+	if (rcode)
+	{
+		printf("Error getting %s\r\n", secretID->name);
+		return;
+	}
+
+	printf("\r\n Name: %s\r\n", secretID->name);
+	while (rcode == NSSCS_SUCCESS)
+	{		
+		rcode = miCASA_GetNextSHSEntry(start,
+										secHandle,
+										&keyLen,
+										&key,
+										&valLen,
+										&value);
+		start = 0;
+		if (rcode == NSSCS_SUCCESS)
+		{
+			printf("  Key: %s (********)\r\n", key);
+		}	
+		
+		// reset 
+		memset(key, 0, NSSCS_MAX_ID_LEN);
+		keyLen = NSSCS_MAX_ID_LEN;
+		memset(value, 0, 512);
+		valLen = 512;
+	}
+
+	// close handle
+	miCASA_DestroySHSHandle(secHandle);
+
+}
+
+void ListCredentials()
+{
+	int rcode = 0;
+	int i = 0;
+	SSCS_SECRETSTORE_T 			store = {0};
+	SSCS_SECRET_ID_T			appSecretId = {0};
+	SSCS_SECRET_ID_T			sharedSecretId = {0};
+	
+	void						*context;
+	SSCS_KEYCHAIN_ID_T 			kc = {0};
+	
+	SSCS_SH_SECRET_ID_LIST_T	secretIDList = {0};
+	context = OpenStore(&kc);
+	if (context == NULL)
+	{
+		printf("Could not open miCASA store\r\n");
+		return; // NSSCS_E_SYSTEM_FAILURE;
+	}
+
+	secretIDList.secIDList = malloc(128 * sizeof(SSCS_SH_SECRET_ID_T));
+	if (secretIDList.secIDList == NULL)
+	{
+		printf("Memory failure\r\n");
+		return;
+	}
+
+	// set size of buffer
+	secretIDList.enumHandle = 0;
+	secretIDList.returnedIDs = 128;
+
+	rcode = miCASAEnumerateSecretIDs(context, 
+										&kc,					//SSCS_KEYCHAIN_ID_T			*	keyChainID, 
+										0,						//uint32_t						ssFlags, 
+										NULL,					//SSCS_SRCH_KEY_T				*	searchKey, 
+										&secretIDList,			//SSCS_SH_SECRET_ID_LIST_T	*	secretIDList, 
+										NULL					//SSCS_EXT_T					*	ext
+									);
+
+	if (rcode)
+	{
+		printf("Enumerate secretIDs returned %x\r\n", rcode);
+	}
+	else
+	{
+		printf("Found %d credential sets\r\n", secretIDList.returnedIDs);
+		for (i=0; i<secretIDList.returnedIDs; i++)
+		{
+			//printf("%s\r\n", secretIDList.secIDList[i].name);
+			DisplaySecretEx(context, &kc, &secretIDList.secIDList[i]);
+		}
+	}
+
+	if (secretIDList.secIDList)
+		free(secretIDList.secIDList);
+
+	// close it	
+	CloseStore(context);
+
+}
+
+void WriteKey(char* keyvalue)
+{		
+	int						rcode = 0;
+	void					*context;
+	
+	SSCS_SECRET_ID_T		appSecretId = {0};
+	SSCS_SECRET_ID_T		sharedSecretId = {0};
+	
+	SSCS_KEYCHAIN_ID_T 		kc = {0};	
+	SSCS_EXT_T				ext = {0};	
+	
+	
+	context = OpenStore(&kc);
+	if (context == NULL)
+	{
+		return; // NSSCS_E_SYSTEM_FAILURE;
+	}
+
+	appSecretId.len = sscs_Utf8Strlen(credName) + 1;
+	sscs_Utf8Strcpy(appSecretId.id, credName);
+
+	value = keyvalue;
+
+	rcode = miCASAWriteKey(context, 
+							0, 
+							&kc, 
+							&appSecretId, 
+							keyName, 
+							strlen(keyName)+1, 
+							value, 
+							strlen(value)+1, 
+							NULL, 
+							&ext);
+
+	CloseStore(context);
+
+	if (rcode)
+	{
+		printf("miCASAWriteKey returned %d\r\n", rcode);		
+	}	
+}
+
+
+
+void DisplaySecret(SSCS_SH_SECRET_ID_T *secret)
+{
+	void *context = 0;
+	SSCS_KEYCHAIN_ID_T kc;
+	context = OpenStore(&kc);
+
+	if (context != NULL)
+	{
+		DisplaySecretEx(context, &kc, secret);
+		CloseStore(context);
+	}
+}
+
+void RemoveSecret(SSCS_SH_SECRET_ID_T *secret)
+{
+	void *context = 0;
+	int32_t rcode = 0;
+	
+	SSCS_KEYCHAIN_ID_T kc;
+	context = OpenStore(&kc);
+
+	if (context != NULL)
+	{		
+		miCASARemoveSecret(context, &kc, 0, secret, NULL, NULL);
+		CloseStore(context);
+	}
+}
+
+
+
+/*  */
+/*
+ * NAME - sss_GetOpt
+ *
+ * DESCRIPTION
+ *	An implementation of the Unix getopt() function.
+ *
+ */
+int sss_GetOpt( int nArgc, char **nArgv, char *optStr )
+{ /* beginning of the call */
+/* ########################## DECLARATIONS START HERE ######################### */
+
+	static	char		*place = ERRMSG;
+			char		*nxtOpt;
+
+/* ############################## CODE STARTS HERE ############################ */
+	
+	if(!*place)  
+	{
+		if((optIdx >= nArgc) ||
+			((*(place = nArgv[optIdx]) != '-')
+				&& (*(place = nArgv[optIdx]) != '/')) ||
+					(!*++place))
+		{
+			return(-1);
+		}
+
+		if((*place == '-') || (*place == '/'))
+		{
+			++optIdx;
+			return(-1);
+		}
+	}
+
+	if((optionString = (int)*place++) == (int)'=' || 
+			!(nxtOpt = strchr(optStr, optionString))) 
+	{
+		if(!*place) 
+		{
+			++optIdx;
+		}
+
+		return(BADCHAR);
+	}
+
+	if(*++nxtOpt != '=') 
+	{
+		optArg = NULL;
+		if(!*place) 
+		{
+			++optIdx;
+		}
+	}
+	else 
+	{
+		if(*place)
+		{
+			optArg = place + 1;
+		}
+		else if(nArgc <= ++optIdx) 
+		{
+			place = ERRMSG;
+			return(BADCHAR);
+		}
+	 	else 
+		{
+	 		optArg = nArgv[optIdx];
+		}
+
+		place = ERRMSG;
+		++optIdx;
+	}
+	
+	//printf("option string %d\r\n", optionString);
+	return(optionString);
+
+	/* ########################## CODE ENDS HERE ######################### */
+} /* end of GetOPt */
+
+
+
+/*
+ * NAME - main
+ *
+ * DESCRIPTION
+ *	miCASA test program.		   
+ *		   
+ */
+int	main
+(
+	int 		argc, 
+	char 		**argv
+)
+{ /* beginning of the call */
+/* ########################## DECLARATIONS START HERE ######################### */
+	
+
+/* ############################## CODE STARTS HERE ############################ */
+
+	int	c;
+	SSCS_SH_SECRET_ID_T tempSecret = {0};
+	char *keyvalue = NULL;
+	keyvalue = malloc(256);
+	memset(keyvalue, 0, 256);
+
+	//ListCredentials();
+
+	if (argc < 2)
+	{
+		printf("Try 'CASAcli -h' for more infomation\r\n");
+		return 0;
+	}
+	
+	while ((c = sss_GetOpt(argc, argv, "lLhHsSgGdDn=N=k=K=u=U=")) != -1)
+	{
+		//printf("processing arg \r\n");
+		switch(c)
+		{
+			case 'l':
+			case 'L':
+				iAction = LISTCREDS;
+				//ListCredentials();
+				break;
+
+			case 's':
+			case 'S':				
+				iAction = SETCRED;
+				break;
+
+			case 'g':
+			case 'G':				
+				iAction = GETCRED;
+				break;
+
+			case 'd':
+			case 'D':
+				iAction = DELCRED;
+				break;
+
+			case 'n':
+			case 'N':
+				credName = optArg;
+				break;
+
+			case 'k':
+			case 'K':
+				keyName = optArg;				
+				break;
+
+			case 'u':
+			case 'U':
+				uid = optArg;
+				printf("UID: %s\r\n", uid);
+				break;
+
+
+			default:				
+				printf("\r\n");
+				printf(" Description:\r\n");
+				printf("   This program is a simple utility to display, set, and delete\r\n");
+				printf("   credentials used by services on this computer.  Because credentials\r\n");
+				printf("   are scoped by the UID of the running process, you must run\r\n");
+				printf("   this utility as the same UID as the service being configured.\r\n");
+				printf("\r\n");
+
+				printf(" Usage: CASAcli [OPTIONS]\r\n");            
+				printf("   Options\r\n");
+				printf("      -l         List all credentials, keys, and values used by services\r\n");
+				printf("      -h         Displays this help screen\r\n");
+				printf("\r\n");
+				printf("      -s         Sets the key and value of the named credential\r\n");
+				printf("      -g         Gets and displays the keys and values of the named credential\r\n");
+				printf("      -d         Delete all keys and values of the named credential\r\n");
+				printf("\r\n");
+				printf("      -n [name]  Specify the credential name\r\n");
+				printf("      -k [key]   Specify the key name to set\r\n");
+				printf("      -u [uid]   Specify the UID of the process\r\n");
+				
+				
+				printf("\r\n");
+
+				printf("   Examples\r\n");
+				printf("       CASAcli -g -n MyCredential\r\n");
+				printf("       CASAcli -d -n MyCredential\r\n");
+				printf("       KEYVALUE=admin CASAcli -s -n MyCredential -k CN\r\n");            
+				printf("       KEYVALUE=password CASAcli -s -n MyCredential -k Password\r\n");  
+				
+				printf("\r\n");
+
+				exit(0);
+		}
+	} 
+
+	// set the UID if there is one
+#ifdef LINUX
+	if (uid != NULL)
+	{
+		printf("Setting UID to %s\r\n", uid);
+		SetUID(atoi(uid));
+	}
+#endif
+
+	// now call the api's
+	// if we get here, check for operation
+	if (iAction > 0)
+	{
+		// check for cred name
+		if ((iAction != LISTCREDS) && (credName == NULL))
+		{
+			printf("No credential name entered\r\n");
+			exit(0);			
+		}
+
+	
+		switch (iAction)
+		{		
+			case LISTCREDS:
+				ListCredentials();
+				break;
+
+			case GETCRED:
+				{
+					printf("Getting %s\r\n", credName);
+					tempSecret.type = 2;
+					tempSecret.len = sscs_Utf8Strlen(credName) + 1;
+					if (tempSecret.len < NSSCS_MAX_SECRET_ID_LEN)
+					{
+						sscs_Utf8Strncpy(tempSecret.name, credName, tempSecret.len);
+						DisplaySecret(&tempSecret);
+					}
+					else
+					{
+						printf("Credential name too long\r\n");
+					}
+					
+					break;
+				}
+
+			case SETCRED:
+				{
+					if (keyName != NULL) 
+					{
+						printf("Setting %s\r\n", credName);
+						keyvalue = getenv("KEYVALUE");
+						if (keyvalue != NULL)
+						{
+							WriteKey(keyvalue);
+						}
+						else
+						{
+							printf("No value set\r\n");
+							printf("Example: KEYVALUE=admin CASAcli -s -n Name -k cn\r\n");
+							return;
+						}						
+					}
+					else
+					{
+						printf("No key name entered\r\n");
+					}
+					break;
+				}
+			case DELCRED:
+				{
+					printf("Deleting %s\r\n", credName);
+					tempSecret.type = 2;
+					tempSecret.len = sscs_Utf8Strlen(credName) + 1;
+					if (tempSecret.len < NSSCS_MAX_SECRET_ID_LEN)
+					{
+						sscs_Utf8Strncpy(tempSecret.name, credName, tempSecret.len);
+						RemoveSecret(&tempSecret);
+					}
+					else
+					{
+						printf("Credential name too long\r\n");
+					}
+					break;
+				}
+
+		}
+
+	}
+	
+	exit(0);
+
+/* ########################## CODE ENDS HERE ##################### */
+}
diff --git a/CASA/micasadk/sscs_ndk.c b/CASA/micasadk/sscs_ndk.c
index 275f7750..773d8442 100644
--- a/CASA/micasadk/sscs_ndk.c
+++ b/CASA/micasadk/sscs_ndk.c
@@ -449,11 +449,13 @@ static int32_t sscsshs_UnescapeSecretIDBuf
 
 	do
 	{	// determine the type of secret
-		if((sscs_Utf8Strncmp(secID->id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED)) == 0)
+		if((sscs_Utf8Strncmp(secID->id, SSCS_CRED_SET_DELIMITED, SSCS_CRED_SET_CHARS_DELIMITED-1)) == 0)
 		{
 			shSecID->type |= SSCS_CREDENTIAL_TYPE_F;
 			tmpSecID.len = SSCS_CRED_SET_CHARS_DELIMITED;
-			sscs_Utf8Strncpy(tmpSecID.id, secID->id, SSCS_CRED_SET_CHARS_DELIMITED);
+			//sscs_Utf8Strncpy(tmpSecID.id, secID->id, SSCS_CRED_SET_CHARS_DELIMITED);
+			//strncpy(tmpSecID.id, secID->id, SSCS_CRED_SET_CHARS_DELIMITED);
+			
 			break;
 		}
 
@@ -479,7 +481,7 @@ static int32_t sscsshs_UnescapeSecretIDBuf
 	while(1);
 
 	// start passed the tag
-	for(k = i = tmpSecID.len; i < len; i++)
+	for(k=0, i=tmpSecID.len - 1; i <= len; i++)
 	{
 		rc = NSSCS_SUCCESS;
 		if(secID->id[i] == (SS_UTF8_T)'\\')
@@ -505,7 +507,7 @@ static int32_t sscsshs_UnescapeSecretIDBuf
 		}
 	} // end for ...
 
-	shSecID->len = tmpSecID.len + k - 1;
+	shSecID->len = k-1; //tmpSecID.len + k - 1;
 	sscs_Utf8Strncpy(shSecID->name, tmpSecID.id, shSecID->len);
 //	shSecID->len = k;
 
diff --git a/CASA/package/linux/CASA.spec.in b/CASA/package/linux/CASA.spec.in
index affe06ae..0fc4f070 100644
--- a/CASA/package/linux/CASA.spec.in
+++ b/CASA/package/linux/CASA.spec.in
@@ -131,10 +131,9 @@ install -m 755 %{_lib}/%{cfg}/Novell.CASA.DataEngines.FireFox.dll %{buildroot}%{
 install -m 755 %{binsource}/%{cfg}/micasad.exe %{buildroot}%{bin_prefix}/bin
 install -m 755 %{binsource}/%{cfg}/micasad-init %{buildroot}%{bin_prefix}/bin
 install -m 755 %{binsource}/%{cfg}/CASAManager.exe %{buildroot}%{bin_prefix}/bin 
-install -m 755 %{binsource}/%{cfg}/CASAcli.exe %{buildroot}%{bin_prefix}/bin 
+install -m 755 %{binsource}/%{cfg}/CASAcli %{buildroot}%{bin_prefix}/bin 
 install -m 755 gui/CASAManager.sh %{buildroot}%{bin_prefix}/bin
 install -m 755 gui/CASAManager.exe.config %{buildroot}%{bin_prefix}/bin
-install -m 755 cli/CASAcli %{buildroot}%{bin_prefix}/bin
 install -m 644 gui/images/* %{buildroot}%{prefix}/CASA/images
 install -m 644 gui/help/en/* %{buildroot}%{prefix}/CASA/help/en
 install -m 755 micasad/startup/micasad %{buildroot}/etc/init.d
@@ -254,7 +253,6 @@ rm -rf $RPM_BUILD_ROOT
 
 %files cli
 %defattr(-,root,root)
-%{bin_prefix}/bin/CASAcli.exe
 %{bin_prefix}/bin/CASAcli
 
 %files devel