summaryrefslogtreecommitdiff
path: root/examples/libmsrpc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/libmsrpc')
-rw-r--r--examples/libmsrpc/cacusermgr/Makefile22
-rw-r--r--examples/libmsrpc/cacusermgr/cacusermgr.c344
-rw-r--r--examples/libmsrpc/cacusermgr/cacusermgr.h65
-rw-r--r--examples/libmsrpc/cacusermgr/mgr_group.c210
-rw-r--r--examples/libmsrpc/cacusermgr/mgr_user.c416
-rw-r--r--examples/libmsrpc/cacusermgr/util.c343
-rw-r--r--examples/libmsrpc/test/Makefile99
-rw-r--r--examples/libmsrpc/test/README8
-rw-r--r--examples/libmsrpc/test/lsa/ear.c261
-rw-r--r--examples/libmsrpc/test/lsa/lsaenum.c96
-rw-r--r--examples/libmsrpc/test/lsa/lsaenumprivs.c79
-rw-r--r--examples/libmsrpc/test/lsa/lsapol.c87
-rw-r--r--examples/libmsrpc/test/lsa/lsapriv.c113
-rw-r--r--examples/libmsrpc/test/lsa/lsaq.c245
-rw-r--r--examples/libmsrpc/test/lsa/lsatrust.c151
-rw-r--r--examples/libmsrpc/test/reg/regdelete.c102
-rw-r--r--examples/libmsrpc/test/reg/regkey.c76
-rw-r--r--examples/libmsrpc/test/reg/regkeycreate.c115
-rw-r--r--examples/libmsrpc/test/reg/regkeyenum.c99
-rw-r--r--examples/libmsrpc/test/reg/regopen.c66
-rw-r--r--examples/libmsrpc/test/reg/regopenkey.c69
-rw-r--r--examples/libmsrpc/test/reg/regqueryval.c79
-rw-r--r--examples/libmsrpc/test/reg/regsetval.c59
-rw-r--r--examples/libmsrpc/test/reg/regvalenum.c103
-rw-r--r--examples/libmsrpc/test/reg/security.c74
-rw-r--r--examples/libmsrpc/test/reg/shutdown.c68
-rw-r--r--examples/libmsrpc/test/sam/adduser.c92
-rw-r--r--examples/libmsrpc/test/sam/disable.c63
-rw-r--r--examples/libmsrpc/test/sam/dominfo.c55
-rw-r--r--examples/libmsrpc/test/sam/enable.c64
-rw-r--r--examples/libmsrpc/test/sam/samenum.c117
-rw-r--r--examples/libmsrpc/test/sam/samgroup.c480
-rw-r--r--examples/libmsrpc/test/sam/samlookup.c140
-rw-r--r--examples/libmsrpc/test/sam/samuser.c294
-rw-r--r--examples/libmsrpc/test/smbc_test/smbc.c87
-rw-r--r--examples/libmsrpc/test/svcctl/svc.c303
-rw-r--r--examples/libmsrpc/test/test_util.c408
-rw-r--r--examples/libmsrpc/test/test_util.h31
38 files changed, 5583 insertions, 0 deletions
diff --git a/examples/libmsrpc/cacusermgr/Makefile b/examples/libmsrpc/cacusermgr/Makefile
new file mode 100644
index 0000000000..ab8bea410e
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/Makefile
@@ -0,0 +1,22 @@
+CC=gcc
+INCLUDES= -I`pwd` -I../../../source/ -I../../../source/include -I../../../source/ubiqx
+
+DEFS= -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+
+CFLAGS= -g -Wall -ansi $(INCLUDES)
+
+OBJ= util.o mgr_group.o mgr_user.o
+
+LDFLAGS=-L. -L../../bin/
+LIBS=../../../source/bin/libmsrpc.so
+
+all: cacusermgr
+
+cacusermgr: cacusermgr.o $(OBJ)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(OBJ) $(LIBS)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $< -o $@
+
+clean:
+ rm -f *.o cacusermgr
diff --git a/examples/libmsrpc/cacusermgr/cacusermgr.c b/examples/libmsrpc/cacusermgr/cacusermgr.c
new file mode 100644
index 0000000000..77dd2505f6
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/cacusermgr.c
@@ -0,0 +1,344 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * cacusermgr main implementation.
+ *
+ * Copyright (C) Chris Nicholls 2005
+ *
+ * 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. */
+
+#include "cacusermgr.h"
+
+#define DEFAULT_MENU_LINES 15
+
+
+void create_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
+ struct SamCreateUser cu;
+ struct SamCreateGroup cg;
+
+ fstring in;
+ fstring tmp;
+
+ if(!hnd || !mem_ctx || !dom_hnd) {
+ printf("No Handle to SAM.\n");
+ return;
+ }
+
+ /*the menu*/
+ in[0] = '\0';
+ while(in[0] != 'c' && in[0] != 'C' && in[0] != 'q' && in[0] != 'Q') {
+ printf("\n");
+ printf("[u] Create User\n");
+ printf("[g] Create Group\n");
+ printf("[m] Create Machine Account\n");
+ printf("[c] Cancel\n\n");
+
+ printf("Command: ");
+ mgr_getline(in);
+
+ printf("\n");
+
+ switch(in[0]) {
+ case 'u': /*create user*/
+ case 'U':
+ ZERO_STRUCT(cu);
+ cu.in.dom_hnd = dom_hnd;
+ cu.in.acb_mask = ACB_NORMAL;
+
+ printf("Enter name: ");
+ mgr_getline(tmp);
+ cu.in.name = talloc_strdup(mem_ctx, tmp);
+
+ if(!cac_SamCreateUser(hnd, mem_ctx, &cu)) {
+ printerr("Could not create user.", hnd->status);
+ }
+ else {
+ user_menu(hnd, mem_ctx, dom_hnd, cu.out.user_hnd);
+ }
+
+ /*this will break the loop and send us back to the main menu*/
+ in[0] = 'c';
+ break;
+
+ case 'g': /*create group*/
+ case 'G':
+ ZERO_STRUCT(cg);
+ cg.in.dom_hnd = dom_hnd;
+ cg.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ printf("Enter name: ");
+ mgr_getline(tmp);
+ cg.in.name = talloc_strdup(mem_ctx, tmp);
+
+ if(!cac_SamCreateGroup(hnd, mem_ctx, &cg)) {
+ printerr("Could not create group.", hnd->status);
+ }
+ else {
+ group_menu(hnd, mem_ctx, dom_hnd, cg.out.group_hnd);
+ }
+
+ /*this will break the loop and send us back to the main menu*/
+ in[0] = 'c';
+ break;
+
+ case 'm': /*create machine account*/
+ case 'M':
+ ZERO_STRUCT(cu);
+ cu.in.dom_hnd = dom_hnd;
+ cu.in.acb_mask = ACB_WSTRUST;
+
+ printf("Enter machine name: ");
+ mgr_getline(tmp);
+
+ /*make sure we have a $ on the end*/
+ if(tmp[strlen(tmp) - 1] != '$')
+ cu.in.name = talloc_asprintf(mem_ctx, "%s$", tmp);
+ else
+ cu.in.name = talloc_strdup(mem_ctx, tmp);
+
+ strlower_m(cu.in.name);
+
+ printf("Creating account: %s\n", cu.in.name);
+
+ if(!cac_SamCreateUser(hnd, mem_ctx, &cu)) {
+ printerr("Could not create account.", hnd->status);
+ }
+ else {
+ user_menu(hnd, mem_ctx, dom_hnd, cu.out.user_hnd);
+ }
+
+ /*this will break the loop and send us back to the main menu*/
+ in[0] = 'c';
+ break;
+
+ case 'c': /*cancel*/
+ case 'C':
+ case 'q':
+ case 'Q':
+ /*do nothing*/
+ break;
+
+ default:
+ printf("Invalid option\n");
+ }
+ }
+
+ return;
+}
+
+void main_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
+ fstring in;
+
+ uint32 rid_type = 0;
+
+ struct SamOpenUser openu;
+ struct SamOpenGroup openg;
+ struct SamEnumUsers enumu;
+ struct SamEnumGroups enumg;
+ struct SamFlush flush;
+
+ char *name = NULL;
+ uint32 rid = 0;
+
+ if(!hnd || !mem_ctx || !dom_hnd) {
+ printf("No handle to SAM.\n");
+ return;
+ }
+
+ /*initialize this here and don't worry about it later*/
+ ZERO_STRUCT(flush);
+ flush.in.dom_hnd = dom_hnd;
+
+ in[0] = '\0';
+
+ /*handle the menu and commands*/
+ while(in[0] != 'q' && in[0] != 'Q') {
+ printf("\n");
+
+ printf("[o] Open User or Group\n");
+ printf("[c] Create Account or Group\n");
+ printf("[u] List Users\n");
+ printf("[g] List Groups\n");
+ printf("[m] List Machine Accounts\n");
+ printf("[q] Quit\n\n");
+
+ printf("Command: ");
+
+ mgr_getline(in);
+
+ printf("\n");
+
+ switch(in[0]) {
+ case 'o': /*open user or group*/
+ case 'O':
+ printf("Enter RID or Name: ");
+ rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &rid, &name);
+
+ if(rid_type == CAC_USER_RID) {
+ ZERO_STRUCT(openu);
+ openu.in.dom_hnd = dom_hnd;
+ openu.in.rid = rid;
+ openu.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &openu))
+ printerr("Could not open user.", hnd->status);
+ else {
+ user_menu(hnd, mem_ctx, dom_hnd, openu.out.user_hnd);
+
+ if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
+ printerr("Lost handle while flushing SAM.", hnd->status);
+ /*we want to quit*/
+ in[0] = 'q';
+ }
+ }
+ }
+ else if(rid_type == CAC_GROUP_RID) {
+ ZERO_STRUCT(openg);
+ openg.in.dom_hnd = dom_hnd;
+ openg.in.rid = rid;
+ openg.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenGroup(hnd, mem_ctx, &openg))
+ printerr("Could not open group.", hnd->status);
+ else {
+ group_menu(hnd, mem_ctx, dom_hnd, openg.out.group_hnd);
+
+ if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
+ printerr("Lost handle while flushing SAM.", hnd->status);
+ /*we want to quit*/
+ in[0] = 'q';
+ }
+ }
+ }
+ else {
+ printf("Unknown RID/Name.\n");
+ }
+
+ break;
+
+ case 'c': /*create account/group*/
+ case 'C':
+ create_menu(hnd, mem_ctx, dom_hnd);
+ if(!cac_SamFlush(hnd, mem_ctx, &flush)) {
+ printerr("Lost handle while flushing SAM.", hnd->status);
+ /*we want to quit*/
+ in[0] = 'q';
+ }
+ break;
+
+ case 'u': /*list users*/
+ case 'U':
+ ZERO_STRUCT(enumu);
+ enumu.in.dom_hnd = dom_hnd;
+ enumu.in.acb_mask = ACB_NORMAL;
+
+ printf("Users:\n");
+ while(cac_SamEnumUsers(hnd, mem_ctx, &enumu)) {
+ print_rid_list(enumu.out.rids, enumu.out.names, enumu.out.num_users);
+ }
+ if(CAC_OP_FAILED(hnd->status))
+ printerr("Error occured while enumerating users.", hnd->status);
+ break;
+
+ case 'g': /*list groups*/
+ case 'G':
+ ZERO_STRUCT(enumg);
+ enumg.in.dom_hnd = dom_hnd;
+
+ while(cac_SamEnumGroups(hnd, mem_ctx, &enumg)) {
+ print_rid_list( enumg.out.rids, enumg.out.names, enumg.out.num_groups);
+ }
+
+ if(CAC_OP_FAILED(hnd->status))
+ printerr("Error occured while enumerating groups.", hnd->status);
+ break;
+
+ case 'm': /*list machine accounts*/
+ case 'M':
+ ZERO_STRUCT(enumu);
+ enumu.in.dom_hnd = dom_hnd;
+ enumu.in.acb_mask = ACB_WSTRUST;
+
+ printf("Users:\n");
+ while(cac_SamEnumUsers(hnd, mem_ctx, &enumu)) {
+ print_rid_list( enumu.out.rids, enumu.out.names, enumu.out.num_users);
+ }
+ if(CAC_OP_FAILED(hnd->status))
+ printerr("Error occured while enumerating accounts.", hnd->status);
+ break;
+
+ case 'q': /*quit*/
+ case 'Q':
+ /*just do nothing*/
+ break;
+
+ default:
+ printf("Invalid Command.\n");
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ struct SamOpenDomain sod;
+
+ mem_ctx = talloc_init("cacusermgr");
+ if(!mem_ctx) {
+ printf("Could not initialize Talloc Context\n");
+ exit(-1);
+ }
+
+ /**first initialize the server handle with what we have*/
+ hnd = cac_NewServerHandle(True);
+ if(!hnd) {
+ printf("Could not create server handle\n");
+ exit(-1);
+ }
+
+ /*fill in the blanks*/
+ if(!process_cmd_line(hnd, mem_ctx, argc, argv))
+ usage();
+
+ if(!cac_Connect(hnd, NULL)) {
+ printf("Could not connect to server %s. %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ /*open the domain sam*/
+ ZERO_STRUCT(sod);
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ printf("Could not open handle to domain SAM. %s\n", nt_errstr(hnd->status));
+ goto cleanup;
+ }
+
+ main_menu(hnd, mem_ctx, sod.out.dom_hnd);
+
+cleanup:
+
+ if(sod.out.dom_hnd)
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ if(sod.out.sam)
+ cac_SamClose(hnd, mem_ctx, sod.out.sam);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/cacusermgr/cacusermgr.h b/examples/libmsrpc/cacusermgr/cacusermgr.h
new file mode 100644
index 0000000000..01dbb60acf
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/cacusermgr.h
@@ -0,0 +1,65 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * cacusermgr definitions and includes.
+ *
+ * Copyright (C) Chris Nicholls 2005
+ *
+ * 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. */
+
+#ifndef CACUSERMGR_H_
+#define CACUSERMGR_H_
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+/*used for the simple pager - mgr_page()*/
+#define DEFAULT_SCREEN_LINES 20
+
+/**************
+ * prototypes *
+ **************/
+
+/*util.c*/
+void usage();
+int process_cmd_line(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, int argc, char **argv);
+void mgr_getline(fstring line);
+void mgr_page(uint32 line_count);
+uint32 rid_or_name(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, uint32 *rid, char **name);
+char *get_new_password(TALLOC_CTX *mem_ctx);
+void printerr(const char *msg, NTSTATUS status);
+void print_rid_list(uint32 *rids, char **names, uint32 num_rids);
+void print_lookup_records(CacLookupRidsRecord *map, uint32 num_rids);
+int list_groups(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd);
+void list_privs(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, CacUserInfo *info);
+void add_privs(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, CacUserInfo *info);
+void list_users(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd);
+
+void mgr_GetAuthDataFn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword);
+
+
+/*mgr_group.c*/
+void group_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, POLICY_HND *group_hnd);
+
+/*mgr_user.c*/
+void user_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, POLICY_HND *user_hnd);
+
+#endif /*CACUSERMGR_H_*/
diff --git a/examples/libmsrpc/cacusermgr/mgr_group.c b/examples/libmsrpc/cacusermgr/mgr_group.c
new file mode 100644
index 0000000000..a936433e60
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/mgr_group.c
@@ -0,0 +1,210 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * cacusermgr group implementation.
+ *
+ * Copyright (C) Chris Nicholls 2005
+ *
+ * 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. */
+
+#include "cacusermgr.h"
+
+CacGroupInfo *get_group_info(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) {
+ struct SamGetGroupInfo getinfo;
+
+ if(!hnd || !mem_ctx ||!group_hnd)
+ return NULL;
+
+ ZERO_STRUCT(getinfo);
+ getinfo.in.group_hnd = group_hnd;
+
+ if(!cac_SamGetGroupInfo(hnd, mem_ctx, &getinfo))
+ printerr("Could not get group info.", hnd->status);
+
+ return getinfo.out.info;
+}
+
+void print_group_info(CacGroupInfo *info) {
+ if(!info)
+ return;
+
+ printf(" Group Name : %s\n", info->name);
+ printf(" Description : %s\n", info->description);
+ printf(" Number of Members : %d\n", info->num_members);
+}
+
+CacGroupInfo *modify_group_info(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) {
+ struct SamSetGroupInfo setinfo;
+ CacGroupInfo *info = NULL;
+ fstring tmp;
+
+ info = get_group_info(hnd, mem_ctx, group_hnd);
+
+ if(!info)
+ return NULL;
+
+ printf("Description [%s]: ", info->description);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->description = talloc_strdup(mem_ctx, tmp);
+
+ ZERO_STRUCT(setinfo);
+ setinfo.in.group_hnd = group_hnd;
+ setinfo.in.info = info;
+
+ if(!cac_SamSetGroupInfo(hnd, mem_ctx, &setinfo)) {
+ printerr("Could not set info.", hnd->status);
+ info = NULL;
+ }
+
+ return info;
+}
+
+void group_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, POLICY_HND *group_hnd) {
+ CacGroupInfo *info = NULL;
+ int rid_type = 0;
+
+ fstring in;
+
+ char *buf;
+
+ struct SamGetGroupMembers getmem;
+ struct SamGetNamesFromRids getnames;
+ struct SamAddGroupMember add;
+ struct SamRemoveGroupMember del;
+
+ info = get_group_info(hnd, mem_ctx, group_hnd);
+
+ printf("\n");
+ print_group_info(info);
+
+ while(in[0] != 'b' && in[0] != 'B' && in[0] != 'q' && in[0] != 'Q') {
+ printf("\n");
+ printf("[m] List Group Members\n");
+ printf("[a] Add User To Group\n");
+ printf("[r] Remove User From Group\n");
+ printf("[l] List Users\n");
+ printf("[v] View Group Info\n");
+ printf("[d] Set Group Description\n");
+ printf("[x] Delete Group\n");
+ printf("[b] Back\n\n");
+
+ printf("Command: ");
+ mgr_getline(in);
+
+ printf("\n");
+
+ switch(in[0]) {
+ case 'a': /*add member to group*/
+ case 'A':
+ ZERO_STRUCT(add);
+ add.in.group_hnd = group_hnd;
+
+ printf("Enter RID or Name: ");
+ rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &add.in.rid, &buf);
+
+ if(rid_type != CAC_USER_RID) {
+ printf("Invalid User.\n");
+ break;
+ }
+
+ if(!cac_SamAddGroupMember(hnd, mem_ctx, &add)) {
+ printerr("Could not add user to group.", hnd->status);
+ }
+ break;
+
+ case 'r': /*remove user from group*/
+ case 'R':
+ ZERO_STRUCT(del);
+ del.in.group_hnd = group_hnd;
+
+ printf("Enter RID or Name: ");
+ rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &del.in.rid, &buf);
+
+ if(rid_type != CAC_USER_RID) {
+ printf("Invalid User.\n");
+ break;
+ }
+
+ if(!cac_SamRemoveGroupMember(hnd, mem_ctx, &del)) {
+ printerr("Could not remove use from group.", hnd->status);
+ }
+ break;
+
+ case 'l': /*list users*/
+ case 'L':
+ list_users(hnd, mem_ctx, dom_hnd);
+ break;
+
+ case 'm': /*list members*/
+ case 'M':
+ ZERO_STRUCT(getmem);
+ getmem.in.group_hnd = group_hnd;
+
+ if(!cac_SamGetGroupMembers(hnd, mem_ctx, &getmem)) {
+ printerr("Could not get members.", hnd->status);
+ break;
+ }
+
+ ZERO_STRUCT(getnames);
+ getnames.in.dom_hnd = dom_hnd;
+ getnames.in.rids = getmem.out.rids;
+ getnames.in.num_rids = getmem.out.num_members;
+
+ if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &getnames)) {
+ printerr("Could not lookup names.", hnd->status);
+ break;
+ }
+
+ printf("Group has %d members:\n", getnames.out.num_names);
+ print_lookup_records(getnames.out.map, getnames.out.num_names);
+
+ break;
+
+ case 'd': /*set description*/
+ case 'D':
+ info = modify_group_info(hnd, mem_ctx, group_hnd);
+
+ if(info)
+ printf("Set Group Info.\n");
+ break;
+
+ case 'v': /*view info*/
+ case 'V':
+ info = get_group_info(hnd, mem_ctx, group_hnd);
+ print_group_info(info);
+ break;
+
+ case 'x': /*delete group*/
+ case 'X':
+ if(!cac_SamDeleteGroup(hnd, mem_ctx, group_hnd))
+ printerr("Could Not Delete Group.", hnd->status);
+
+ /*we want to go back to the main menu*/
+ in[0] = 'b';
+ break;
+
+ case 'b': /*back*/
+ case 'B':
+ case 'q':
+ case 'Q':
+ break;
+
+ default:
+ printf("Invalid Command.\n");
+ }
+ }
+
+ cac_SamClose(hnd, mem_ctx, group_hnd);
+}
diff --git a/examples/libmsrpc/cacusermgr/mgr_user.c b/examples/libmsrpc/cacusermgr/mgr_user.c
new file mode 100644
index 0000000000..7e2e56499f
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/mgr_user.c
@@ -0,0 +1,416 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * cacusermgr user implementation.
+ *
+ * Copyright (C) Chris Nicholls 2005
+ *
+ * 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. */
+
+#include "cacusermgr.h"
+
+void print_user_info(CacUserInfo *info) {
+ printf("\n");
+ printf(" User Name : %s\n", info->username);
+ printf(" Full Name : %s\n", info->full_name);
+ printf(" Home Dir : %s\n", info->home_dir);
+ printf(" Home Drive : %s\n", info->home_drive);
+ printf(" Profile Path : %s\n", info->profile_path);
+ printf(" Logon Script : %s\n", info->logon_script);
+ printf(" Description : %s\n", info->description);
+ printf(" Workstations : %s\n", info->workstations);
+ printf(" Remote Dial : %s\n", info->dial);
+
+ printf(" Logon Time : %s\n", http_timestring(info->logon_time));
+ printf(" Logoff Time : %s\n", http_timestring(info->logoff_time));
+ printf(" Kickoff Time : %s\n", http_timestring(info->kickoff_time));
+ printf(" Pass last set : %s\n", http_timestring(info->pass_last_set_time));
+ printf(" Pass can set : %s\n", http_timestring(info->pass_can_change_time));
+ printf(" Pass must set : %s\n", http_timestring(info->pass_must_change_time));
+
+ printf(" User RID : 0x%x\n", info->rid);
+ printf(" Group RID : 0x%x\n", info->group_rid);
+ printf(" User Type : ");
+
+ if(info->acb_mask & ACB_NORMAL)
+ printf("Normal User\n");
+ else if(info->acb_mask & ACB_TEMPDUP)
+ printf("Temporary Duplicate Account\n");
+ else if(info->acb_mask & ACB_DOMTRUST)
+ printf("Inter-Domain Trust Account\n");
+ else if(info->acb_mask & ACB_WSTRUST)
+ printf("Workstation Trust Account\n");
+ else if(info->acb_mask & ACB_SVRTRUST)
+ printf("Server Trust Account\n");
+ else
+ printf("\n");
+
+ printf(" Disabled : %s\n", (info->acb_mask & ACB_DISABLED) ? "Yes" : "No");
+ printf(" Locked : %s\n", (info->acb_mask & ACB_AUTOLOCK) ? "Yes" : "No");
+ printf(" Pass Expires : %s\n", (info->acb_mask & ACB_PWNOEXP) ? "No" : "Yes");
+ printf(" Pass Required : %s\n", (info->acb_mask & ACB_PWNOTREQ) ? "No" : "Yes");
+
+}
+
+CacUserInfo *modify_user_info(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) {
+ CacUserInfo *info = NULL;
+ fstring tmp;
+
+ struct SamGetUserInfo getinfo;
+ struct SamSetUserInfo setinfo;
+
+ ZERO_STRUCT(getinfo);
+ ZERO_STRUCT(setinfo);
+
+ getinfo.in.user_hnd = user_hnd;
+
+ if(!cac_SamGetUserInfo(hnd, mem_ctx, &getinfo)) {
+ printerr("Could not get user info.", hnd->status);
+ return NULL;
+ }
+
+ info = getinfo.out.info;
+
+ printf("\n");
+ printf(" User Name [%s]: ", info->username);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->username = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Full Name [%s]: ", info->full_name);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->full_name = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Description [%s]: ", info->description);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->description = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Home Dir [%s]: ", info->home_dir);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->home_dir = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Home Drive [%s]: ", info->home_drive);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->home_drive = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Profile Path [%s]: ", info->profile_path);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->profile_path = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Logon Script [%s]: ", info->logon_script);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->logon_script = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Workstations [%s]: ", info->workstations);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->workstations = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Remote Dial [%s]: ", info->dial);
+ mgr_getline(tmp);
+ if(tmp[0] != '\0')
+ info->dial = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Disabled [%s] (y/n): ", (info->acb_mask & ACB_DISABLED) ? "Yes" : "No");
+ mgr_getline(tmp);
+ if(tmp[0] == 'y' || tmp[0] == 'Y')
+ info->acb_mask |= ACB_DISABLED;
+ else if(tmp[0] == 'n' || tmp[0] == 'N')
+ info->acb_mask ^= (info->acb_mask & ACB_DISABLED) ? ACB_DISABLED : 0x0;
+
+ printf(" Pass Expires [%s] (y/n): ", (info->acb_mask & ACB_PWNOEXP) ? "No" : "Yes");
+ mgr_getline(tmp);
+ if(tmp[0] == 'n' || tmp[0] == 'N')
+ info->acb_mask |= ACB_PWNOEXP;
+ else if(tmp[0] == 'y' || tmp[0] == 'Y')
+ info->acb_mask ^= (info->acb_mask & ACB_PWNOEXP) ? ACB_PWNOEXP : 0x0;
+
+ printf(" Pass Required [%s] (y/n): ", (info->acb_mask & ACB_PWNOTREQ) ? "No" : "Yes");
+ mgr_getline(tmp);
+ if(tmp[0] == 'n' || tmp[0] == 'N')
+ info->acb_mask |= ACB_PWNOTREQ;
+ else if(tmp[0] == 'y' || tmp[0] == 'Y')
+ info->acb_mask ^= (info->acb_mask & ACB_PWNOTREQ) ? ACB_PWNOTREQ : 0x0;
+
+ setinfo.in.user_hnd = user_hnd;
+ setinfo.in.info = info;
+
+ if(!cac_SamSetUserInfo(hnd, mem_ctx, &setinfo)) {
+ printerr("Could not set user info.", hnd->status);
+ }
+
+ return info;
+}
+
+void add_user_to_group(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, CacUserInfo *info, POLICY_HND *dom_hnd) {
+ int rid_type = 0;
+
+ char *tmp = NULL;
+
+ struct SamOpenGroup og;
+ struct SamAddGroupMember add;
+
+ ZERO_STRUCT(og);
+ ZERO_STRUCT(add);
+
+ printf("Group RID or Name:");
+
+ og.in.dom_hnd = dom_hnd;
+ og.in.access = MAXIMUM_ALLOWED_ACCESS;
+ rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &og.in.rid, &tmp);
+
+ if(!cac_SamOpenGroup(hnd, mem_ctx, &og)) {
+ printerr("Could not open group.", hnd->status);
+ return;
+ }
+
+ add.in.group_hnd = og.out.group_hnd;
+ add.in.rid = info->rid;
+
+ if(!cac_SamAddGroupMember(hnd, mem_ctx, &add)) {
+ printerr("Could not add user to group.", hnd->status);
+ }
+
+ cac_SamClose(hnd, mem_ctx, og.out.group_hnd);
+}
+
+void remove_user_from_group(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, CacUserInfo *info, POLICY_HND *dom_hnd) {
+ int rid_type = 0;
+
+ char *tmp = NULL;
+
+ struct SamOpenGroup og;
+ struct SamRemoveGroupMember del;
+
+ ZERO_STRUCT(og);
+ ZERO_STRUCT(del);
+
+ printf("Group RID or Name:");
+
+ og.in.dom_hnd = dom_hnd;
+ og.in.access = MAXIMUM_ALLOWED_ACCESS;
+ rid_type = rid_or_name(hnd, mem_ctx, dom_hnd, &og.in.rid, &tmp);
+
+ if(!cac_SamOpenGroup(hnd, mem_ctx, &og)) {
+ printerr("Could not open group.", hnd->status);
+ return;
+ }
+
+ del.in.group_hnd = og.out.group_hnd;
+ del.in.rid = info->rid;
+
+ if(!cac_SamRemoveGroupMember(hnd, mem_ctx, &del)) {
+ printerr("Could not add user to group.", hnd->status);
+ }
+
+ cac_SamClose(hnd, mem_ctx, og.out.group_hnd);
+}
+
+void user_menu(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, POLICY_HND *user_hnd) {
+ fstring in;
+
+ struct SamGetUserInfo getinfo;
+ struct SamSetPassword setpass;
+ struct SamGetGroupsForUser groups;
+ struct SamGetNamesFromRids gnfr;
+
+ CacUserInfo *info = NULL;
+
+ if(!hnd || !mem_ctx || !user_hnd) {
+ printf("Must open user.\n");
+ return;
+ }
+
+ /*get the userinfo and print it out*/
+ ZERO_STRUCT(getinfo);
+ getinfo.in.user_hnd = user_hnd;
+
+ if(!cac_SamGetUserInfo(hnd, mem_ctx, &getinfo)) {
+ printerr("Could not get info.", hnd->status);
+ info = NULL;
+ }
+ else {
+ info = getinfo.out.info;
+ print_user_info(info);
+ }
+
+ /*now deal with the menu*/
+ in[0] = '\0';
+ while(in[0] != 'b' && in[0] != 'B' && in[0] != 'q' && in[0] != 'Q') {
+ printf("\n");
+ printf("[s] Set Password\n");
+
+ if(info && (info->acb_mask & ACB_DISABLED))
+ printf("[e] Enable User\n");
+ else if(info)
+ printf("[d] Disable User\n");
+
+ printf("[v] View User Info\n");
+ printf("[m] Modify User Info\n");
+ printf("[x] Delete User\n\n");
+
+ printf("[g] List Group Membership\n");
+ printf("[a] Add User To Group\n");
+ printf("[l] List Domain Groups\n");
+ printf("[r] Remove User From Group\n\n");
+
+ printf("[b] Back\n\n");
+
+ printf("Command: ");
+ mgr_getline(in);
+
+ printf("\n");
+
+ switch(in[0]) {
+ case 'g': /*list group membership*/
+ case 'G':
+ ZERO_STRUCT(groups);
+ groups.in.user_hnd = user_hnd;
+
+ if(!cac_SamGetGroupsForUser(hnd, mem_ctx, &groups)) {
+ printerr("Could not get groups.", hnd->status);
+ break;
+ }
+
+ ZERO_STRUCT(gnfr);
+ gnfr.in.dom_hnd = dom_hnd;
+ gnfr.in.rids = groups.out.rids;
+ gnfr.in.num_rids = groups.out.num_groups;
+
+ if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &gnfr)) {
+ printerr("Could not map RIDs to names.", hnd->status);
+ break;
+ }
+
+ print_lookup_records(gnfr.out.map, gnfr.out.num_names);
+
+ break;
+ case 's': /*reset password*/
+ case 'S':
+ ZERO_STRUCT(setpass);
+ setpass.in.user_hnd = user_hnd;
+ setpass.in.password = get_new_password(mem_ctx);
+
+ if(!setpass.in.password) {
+ printf("Out of memory.\n");
+ break;
+ }
+
+ if(!cac_SamSetPassword(hnd, mem_ctx, &setpass)) {
+ printerr("Could not set password.", hnd->status);
+ }
+ else {
+ printf("Reset password.\n");
+ }
+ break;
+
+ case 'e': /*enable user*/
+ case 'E':
+ if(info && !(info->acb_mask & ACB_DISABLED))
+ break;
+
+ if(!cac_SamEnableUser(hnd, mem_ctx, user_hnd)) {
+ printerr("Could not enable user.", hnd->status);
+ }
+ else {
+ printf("Enabled User.\n");
+ /*toggle the disabled ACB bit in our local copy of the info*/
+ info->acb_mask ^= ACB_DISABLED;
+ }
+ break;
+
+ case 'd': /*disable user*/
+ case 'D':
+ if(info && (info->acb_mask & ACB_DISABLED))
+ break;
+
+ if(!cac_SamDisableUser(hnd, mem_ctx, user_hnd)) {
+ printerr("Could not disable user.", hnd->status);
+ }
+ else {
+ printf("Disabled User.\n");
+ /*toggle the disabled ACB bit in our local copy of the info*/
+ info->acb_mask ^= ACB_DISABLED;
+ }
+ break;
+
+ case 'v': /*view user info*/
+ case 'V':
+ ZERO_STRUCT(getinfo);
+ getinfo.in.user_hnd = user_hnd;
+
+ if(!cac_SamGetUserInfo(hnd, mem_ctx, &getinfo)) {
+ printerr("Could not get info.", hnd->status);
+ info = NULL;
+ }
+ else {
+ info = getinfo.out.info;
+ print_user_info(info);
+ }
+
+ break;
+
+ case 'm': /*modify user info*/
+ case 'M':
+ info = modify_user_info(hnd, mem_ctx, user_hnd);
+
+ if(info)
+ printf("Updated user info.\n");
+ break;
+
+ case 'l': /*list domain groups*/
+ case 'L':
+ list_groups(hnd, mem_ctx, dom_hnd);
+ break;
+
+ case 'a': /*add user to group*/
+ case 'A':
+ add_user_to_group(hnd, mem_ctx, info, dom_hnd);
+ break;
+
+ case 'r': /*remove user from group*/
+ case 'R':
+ remove_user_from_group(hnd, mem_ctx, info, dom_hnd);
+ break;
+
+ case 'x': /*delete user*/
+ case 'X':
+ if(!cac_SamDeleteUser(hnd, mem_ctx, user_hnd))
+ printerr("Could not delete user.", hnd->status);
+
+ /*we want to go back to the main menu*/
+ in[0] = 'b';
+ break;
+
+ case 'b': /*back*/
+ case 'B':
+ case 'q':
+ case 'Q':
+ /*do nothing*/
+ break;
+
+ default:
+ printf("Invalid command.\n");
+ }
+ }
+
+ /*close the user before returning*/
+ cac_SamClose(hnd, mem_ctx, user_hnd);
+}
diff --git a/examples/libmsrpc/cacusermgr/util.c b/examples/libmsrpc/cacusermgr/util.c
new file mode 100644
index 0000000000..1629911812
--- /dev/null
+++ b/examples/libmsrpc/cacusermgr/util.c
@@ -0,0 +1,343 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * cacusermgr utility functions.
+ *
+ * Copyright (C) Chris Nicholls 2005
+ *
+ * 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. */
+
+#include "cacusermgr.h"
+
+/*prints usage and quits*/
+void usage() {
+ printf("Usage:\n");
+ printf(" cacusermgr [options] server\n\n");
+ printf("options:\n");
+ printf(" -u USERNAME Username to login with\n");
+ printf(" -d/-w DOMAIN Domain name\n");
+ printf(" -D LEVEL Debug level\n");
+ printf(" -h Print this message\n");
+
+ exit(1);
+}
+
+/*initializes values in the server handle from the command line returns 0 if there is a problem, non-zero if everything is ok*/
+int process_cmd_line(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, int argc, char **argv) {
+ char op;
+
+ if(!hnd || !mem_ctx || !argc)
+ return 0;
+
+ while( (op = getopt(argc, argv, "u:U:d:w:W:D:h")) != -1) {
+ switch(op) {
+ case 'u': /*username*/
+ case 'U':
+ if(optarg)
+ strncpy(hnd->username, optarg, sizeof(fstring));
+ else
+ usage();
+ break;
+
+ case 'd': /*domain name*/
+ case 'w':
+ case 'W':
+ if(optarg)
+ strncpy(hnd->domain, optarg, sizeof(fstring));
+ else
+ usage();
+ break;
+
+ case 'D': /*debug level*/
+ if(optarg)
+ hnd->debug = atoi(optarg);
+ else
+ usage();
+ break;
+
+ case 'h': /*help*/
+ usage();
+ break;
+
+ case '?':
+ default:
+ printf("Unknown option -%c\n", op);
+ usage();
+ }
+ }
+
+ if(optind >= argc)
+ usage();
+
+ /*whatever is less should be the server*/
+ strncpy(hnd->server, argv[optind], sizeof(fstring));
+
+ return 1;
+}
+
+void mgr_getline(fstring line) {
+
+ fgets(line, sizeof(fstring), stdin);
+
+ if(line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+
+}
+
+/*this is pretty similar to the other get_auth_data_fn's*/
+void mgr_GetAuthDataFn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword)
+
+{
+ char temp[sizeof(fstring)];
+
+ static char authUsername[sizeof(fstring)];
+ static char authWorkgroup[sizeof(fstring)];
+ static char authPassword[sizeof(fstring)];
+ static char authSet = 0;
+
+ char *pass = NULL;
+
+ if (authSet)
+ {
+ strncpy(pWorkgroup, authWorkgroup, maxLenWorkgroup - 1);
+ strncpy(pUsername, authUsername, maxLenUsername - 1);
+ strncpy(pPassword, authPassword, maxLenPassword - 1);
+ }
+ else
+ {
+ if(pWorkgroup[0] != '\0') {
+ strncpy(authWorkgroup, pWorkgroup, maxLenWorkgroup - 1);
+ }
+ else {
+ d_printf("Domain: [%s] ", pWorkgroup);
+ mgr_getline(pWorkgroup);
+
+ if (temp[0] != '\0')
+ {
+ strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
+ strncpy(authWorkgroup, temp, maxLenWorkgroup - 1);
+ }
+ }
+
+
+ if(pUsername[0] != '\0') {
+ strncpy(authUsername, pUsername, maxLenUsername - 1);
+ }
+ else {
+ d_printf("Username: [%s] ", pUsername);
+ mgr_getline(pUsername);
+
+ if (temp[strlen(temp) - 1] == '\n') /* A new line? */
+ {
+ temp[strlen(temp) - 1] = '\0';
+ }
+
+ if (temp[0] != '\0')
+ {
+ strncpy(pUsername, temp, maxLenUsername - 1);
+ strncpy(authUsername, pUsername, maxLenUsername - 1);
+ }
+ }
+ if(pPassword[0] != '\0') {
+ strncpy(authPassword, pPassword, maxLenPassword - 1);
+ }
+ else {
+ pass = getpass("Password: ");
+ if (pass)
+ fstrcpy(temp, pass);
+ if (temp[strlen(temp) - 1] == '\n') /* A new line? */
+ {
+ temp[strlen(temp) - 1] = '\0';
+ }
+ if (temp[0] != '\0')
+ {
+ strncpy(pPassword, temp, maxLenPassword - 1);
+ strncpy(authPassword, pPassword, maxLenPassword - 1);
+ }
+ }
+ authSet = 1;
+ }
+}
+
+void mgr_page(uint32 line_count) {
+
+ if( (line_count % DEFAULT_SCREEN_LINES) != 0)
+ return;
+
+ printf("--Press enter to continue--\n");
+ getchar();
+}
+
+/*reads a line from stdin, figures out if it is a RID or name, gets a CacLookupRidsRecord and then returns the type*/
+uint32 rid_or_name(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd, uint32 *rid, char **name) {
+ fstring line;
+
+ BOOL is_rid = False;
+ uint32 rid_type = 0;
+
+ struct SamGetNamesFromRids getnames;
+ struct SamGetRidsFromNames getrids;
+
+ mgr_getline(line);
+
+ if(strncmp(line, "0x", 2) == 0) {
+ /*then this is a RID*/
+ sscanf( (line + 2), "%x", rid);
+ is_rid = True;
+ }
+ else {
+ /*then this is a name*/
+ *name = talloc_strdup(mem_ctx, line);
+ }
+
+ if(is_rid) {
+ ZERO_STRUCT(getnames);
+
+ getnames.in.dom_hnd = dom_hnd;
+ getnames.in.rids = rid;
+ getnames.in.num_rids = 1;
+
+ cac_SamGetNamesFromRids(hnd, mem_ctx, &getnames);
+
+ if(getnames.out.num_names > 0)
+ rid_type = getnames.out.map[0].type;
+
+ }
+ else {
+ ZERO_STRUCT(getrids);
+
+ getrids.in.dom_hnd = dom_hnd;
+ getrids.in.names = name;
+ getrids.in.num_names = 1;
+
+ cac_SamGetRidsFromNames(hnd, mem_ctx, &getrids);
+
+ if(getrids.out.num_rids > 0) {
+ rid_type = getrids.out.map[0].type;
+
+ /*send back the RID so cac_SamOpenXX() doesn't have to look it up*/
+ *rid = getrids.out.map[0].rid;
+ }
+ }
+
+ return rid_type;
+}
+
+/*print's out some common error messages*/
+void printerr(const char *msg, NTSTATUS status) {
+ if(NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
+ printf("%s You do not have sufficient rights.\n", msg);
+
+ else if(NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER))
+ printf("%s No such user.\n", msg);
+
+ else if(NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_GROUP))
+ printf("%s No such group.\n", msg);
+
+ else if(NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS))
+ printf("%s User already exists.\n", msg);
+
+ else if(NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS))
+ printf("%s Group already exists.\n", msg);
+
+ else
+ printf("%s %s.\n", msg, nt_errstr(status));
+}
+
+char *get_new_password(TALLOC_CTX *mem_ctx) {
+ char *pass1 = NULL;
+
+ pass1 = getpass("Enter new password: ");
+
+ return talloc_strdup(mem_ctx, pass1);
+}
+
+void print_rid_list(uint32 *rids, char **names, uint32 num_rids) {
+ uint32 i = 0;
+
+ if(!names || !rids)
+ return;
+
+ printf(" RID Name\n");
+
+ while(i < num_rids) {
+ printf("[0x%x] [%s]\n", rids[i], names[i]);
+
+ i++;
+
+ mgr_page(i);
+ }
+}
+
+void print_lookup_records(CacLookupRidsRecord *map, uint32 num_rids) {
+ uint32 i = 0;
+
+ if(!map)
+ return;
+
+ printf("RID Name\n");
+
+ while(i < num_rids) {
+ if(map[i].found) {
+ printf("[0x%x] [%s]\n", map[i].rid, map[i].name);
+ }
+
+ i++;
+
+ mgr_page(i);
+ }
+}
+
+int list_groups(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
+ struct SamEnumGroups eg;
+
+ if(!hnd || !mem_ctx || !dom_hnd)
+ return 0;
+
+ ZERO_STRUCT(eg);
+ eg.in.dom_hnd = dom_hnd;
+
+ while(cac_SamEnumGroups(hnd, mem_ctx, &eg))
+ print_rid_list(eg.out.rids, eg.out.names, eg.out.num_groups);
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printerr("Could not enumerate groups.", hnd->status);
+ return 0;
+ }
+
+ return 1;
+}
+
+void list_users(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *dom_hnd) {
+ struct SamEnumUsers eu;
+
+ if(!hnd || !mem_ctx || !dom_hnd)
+ return;
+
+ ZERO_STRUCT(eu);
+ eu.in.dom_hnd = dom_hnd;
+
+ while(cac_SamEnumUsers(hnd, mem_ctx, &eu))
+ print_rid_list(eu.out.rids, eu.out.names, eu.out.num_users);
+
+ if(CAC_OP_FAILED(hnd->status))
+ printerr("Could not enumerate users.", hnd->status);
+}
diff --git a/examples/libmsrpc/test/Makefile b/examples/libmsrpc/test/Makefile
new file mode 100644
index 0000000000..95fa5effa5
--- /dev/null
+++ b/examples/libmsrpc/test/Makefile
@@ -0,0 +1,99 @@
+CC=gcc
+INCLUDES= -I`pwd` -I../../../source/ -I../../../source/include -I../../../source/ubiqx
+
+DEFS= -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
+#CFLAGS= -O -D_SAMBA_BUILD_ -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER -Wdeclaration-after-statement -g $(INCLUDES) $(DEFS) -fPIC
+
+CFLAGS= -g -Wall -ansi $(INCLUDES)
+
+LDFLAGS=-L. -L../../bin/
+LIBS=../../../source/bin/libmsrpc.so
+
+TESTS= lsapol lsaq lsaenum lsaenumprivs lsapriv ear \
+ regkey regopenkey regkeyenum regvalenum regsetval regqueryval regdelete security \
+ adduser samenum samlookup samgroup enable disable dominfo samuser \
+ svc \
+ smbc
+
+all: $(TESTS)
+
+lsapol: lsa/lsapol.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+lsapriv: lsa/lsapriv.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+lsaq: lsa/lsaq.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+lsaenum: lsa/lsaenum.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+lsaenumprivs: lsa/lsaenumprivs.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+lsaaddrights: lsa/lsaaddrights.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+ear: lsa/ear.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+regkey: reg/regkey.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+regopenkey: reg/regopenkey.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+regkeyenum: reg/regkeyenum.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+regkeycreate: reg/regkeycreate.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+
+regvalenum: reg/regvalenum.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+regsetval: reg/regsetval.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+regqueryval: reg/regqueryval.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+regdelete: reg/regdelete.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+security: reg/security.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+adduser: sam/adduser.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+samenum: sam/samenum.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+samlookup: sam/samlookup.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+samgroup: sam/samgroup.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+enable: sam/enable.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+disable: sam/disable.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+samuser: sam/samuser.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+dominfo: sam/dominfo.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+svc: svcctl/svc.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS)
+
+smbc: smbc_test/smbc.o test_util.o
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< test_util.o $(LIBS) ../../../source/bin/libsmbclient.so
+
+clean:
+ rm -f $(TESTS) *.o lsa/*.o reg/*.o sam/*.o
diff --git a/examples/libmsrpc/test/README b/examples/libmsrpc/test/README
new file mode 100644
index 0000000000..9352905b5b
--- /dev/null
+++ b/examples/libmsrpc/test/README
@@ -0,0 +1,8 @@
+This code was written to test the different library functions. However, a simple example of almost every libmsrpc call can be found
+in this code.
+
+notes: most of the programs use a modified smbc_get_auth_data_fn which will not prompt for a user/domain/password so expect flaky results
+if you run the tests with just a server, ie: svc remote_machine
+
+
+If you get errors about the libmsrpc.so object, make sure your LD_LIBRARY_PATH points to /path/to/samba3/source/bin
diff --git a/examples/libmsrpc/test/lsa/ear.c b/examples/libmsrpc/test/lsa/ear.c
new file mode 100644
index 0000000000..8a8202543d
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/ear.c
@@ -0,0 +1,261 @@
+/* connects to an LSA, asks for a list of server names, prints out their sids, then looks up their names from the sids and prints them out again
+ * if you run as lsaq -p, then it will simulate a partial success for cac_GetNamesFromSids. It will try to lookup the server's local and domain sids
+ */
+
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+void fill_conn_info(CacServerHandle *hnd) {
+ pstring domain;
+ pstring username;
+ pstring password;
+ pstring server;
+
+ fprintf(stdout, "Enter domain name: ");
+ fscanf(stdin, "%s", domain);
+
+ fprintf(stdout, "Enter username: ");
+ fscanf(stdin, "%s", username);
+
+ fprintf(stdout, "Enter password (no input masking): ");
+ fscanf(stdin, "%s", password);
+
+ fprintf(stdout, "Enter server (ip or name): ");
+ fscanf(stdin, "%s", server);
+
+ hnd->domain = SMB_STRDUP(domain);
+ hnd->username = SMB_STRDUP(username);
+ hnd->password = SMB_STRDUP(password);
+ hnd->server = SMB_STRDUP(server);
+}
+
+void get_server_names(TALLOC_CTX *mem_ctx, int *num_names, char ***names) {
+ int i = 0;
+ pstring tmp;
+
+ fprintf(stdout, "How many names do you want to lookup?: ");
+ fscanf(stdin, "%d", num_names);
+
+ *names = TALLOC_ARRAY(mem_ctx, char *, *num_names);
+ if(*names == NULL) {
+ fprintf(stderr, "No memory for allocation\n");
+ exit(-1);
+ }
+
+ for(i = 0; i < *num_names; i++) {
+ fprintf(stdout, "Enter name: ");
+ fscanf(stdin, "%s", tmp);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ }
+}
+
+int main(int argc, char **argv) {
+ int i;
+ int result;
+ char **names;
+ int num_names;
+ int num_sids;
+ CacServerHandle *hnd = NULL;
+ POLICY_HND *lsa_pol = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DOM_SID *sid_buf = NULL;
+
+ BOOL sim_partial = False;
+
+ if(argc > 1 && strcmp(argv[1], "-p") == 0)
+ sim_partial = True;
+
+ mem_ctx = talloc_init("lsaq");
+
+ hnd = cac_NewServerHandle(False);
+
+ fill_conn_info(hnd);
+
+ get_server_names(mem_ctx, &num_names, &names);
+
+ /*connect to the PDC and open a LSA handle*/
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error %s.\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ fprintf(stdout, "Connected to server: %s\n", hnd->server);
+
+ struct LsaOpenPolicy lop;
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ lop.in.security_qos = True;
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not get lsa policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ fprintf(stdout, "Opened Policy Handle\n");
+
+ /*just to make things neater*/
+ lsa_pol = lop.out.pol;
+
+ /*fetch the local sid and domain sid for the pdc*/
+
+ struct LsaFetchSid fsop;
+ ZERO_STRUCT(fsop);
+
+ fsop.in.pol = lsa_pol;
+ fsop.in.info_class = (CAC_LOCAL_INFO|CAC_DOMAIN_INFO);
+
+ fprintf(stdout, "fetching SID info for %s\n", hnd->server);
+
+ result = cac_LsaFetchSid(hnd, mem_ctx, &fsop);
+ if(!result) {
+ fprintf(stderr, "Could not get sid for server: %s\n. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+ exit(-1);
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "could not retrieve both domain and local information\n");
+ }
+
+
+ fprintf(stdout, "Fetched SID info for %s\n", hnd->server);
+ if(fsop.out.local_sid != NULL)
+ fprintf(stdout, " domain: %s. Local SID: %s\n", fsop.out.local_sid->domain, sid_string_static(&fsop.out.local_sid->sid));
+
+ if(fsop.out.domain_sid != NULL)
+ fprintf(stdout, " domain: %s, Domain SID: %s\n", fsop.out.domain_sid->domain, sid_string_static(&fsop.out.domain_sid->sid));
+
+ fprintf(stdout, "Looking up sids\n");
+
+
+ struct LsaGetSidsFromNames gsop;
+ ZERO_STRUCT(gsop);
+
+ gsop.in.pol = lsa_pol;
+ gsop.in.num_names = num_names;
+ gsop.in.names = names;
+
+ result = cac_LsaGetSidsFromNames(hnd, mem_ctx, &gsop);
+
+ if(!result) {
+ fprintf(stderr, "Could not lookup any sids!\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "Not all names could be looked up.\nThe following names were not found:\n");
+
+ for(i = 0; i < (num_names - gsop.out.num_found); i++) {
+ fprintf(stdout, " %s\n", gsop.out.unknown[i]);
+ }
+
+ fprintf(stdout, "\n");
+ }
+
+ /*buffer the sids so we can look them up back to names*/
+ num_sids = (sim_partial) ? gsop.out.num_found + 2: gsop.out.num_found;
+ sid_buf = TALLOC_ARRAY(mem_ctx, DOM_SID, num_sids);
+
+ fprintf(stdout, "%d names were resolved: \n", gsop.out.num_found);
+
+
+ i = 0;
+ while(i < gsop.out.num_found) {
+ fprintf(stdout, " Name: %s\n SID: %s\n\n", gsop.out.sids[i].name, sid_string_static(&gsop.out.sids[i].sid));
+
+ sid_buf[i] = gsop.out.sids[i].sid;
+
+ printf("Attempting to open account\n");
+
+ struct LsaOpenAccount loa;
+ ZERO_STRUCT(loa);
+
+ loa.in.pol = lsa_pol;
+ loa.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ loa.in.sid = &gsop.out.sids[i].sid;
+
+ if(!cac_LsaOpenAccount(hnd, mem_ctx, &loa)) {
+ fprintf(stderr, "Could not open account.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ printf("\nEnumerating privs:");
+ struct LsaEnumAccountRights earop;
+ ZERO_STRUCT(earop);
+
+ earop.in.pol = lsa_pol;
+
+ earop.in.sid = &gsop.out.sids[i].sid;
+
+ if(!cac_LsaEnumAccountRights(hnd, mem_ctx, &earop)) {
+ fprintf(stderr, "Could not enumerate account rights.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ int j;
+ printf( "Rights: ");
+ for(j = 0; j < earop.out.num_privs; j++) {
+ printf(" %s\n", earop.out.priv_names[j]);
+ }
+
+ printf("\n");
+
+
+ i++;
+ }
+
+ /*if we want a partial success to occur below, then add the server's SIDs to the end of the array*/
+ if(sim_partial) {
+ sid_buf[i] = fsop.out.local_sid->sid;
+ sid_buf[i+1] = fsop.out.domain_sid->sid;
+ }
+
+ fprintf(stdout, "Looking up Names from SIDs\n");
+
+ struct LsaGetNamesFromSids gnop;
+ ZERO_STRUCT(gnop);
+
+ gnop.in.pol = lsa_pol;
+ gnop.in.num_sids = num_sids;
+ gnop.in.sids = sid_buf;
+
+ result = cac_LsaGetNamesFromSids(hnd, mem_ctx, &gnop);
+
+ if(!result) {
+ fprintf(stderr, "Could not lookup any names!.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "\nNot all SIDs could be looked up.\n. The following SIDs were not found:\n");
+
+ for(i = 0; i < (num_sids - gnop.out.num_found); i++) {
+ fprintf(stdout, "SID: %s\n", sid_string_static(&gnop.out.unknown[i]));
+ }
+
+ fprintf(stdout, "\n");
+ }
+
+ fprintf(stdout, "%d SIDs were resolved: \n", gnop.out.num_found);
+ for(i = 0; i < gnop.out.num_found; i++) {
+ fprintf(stdout, " SID: %s\n Name: %s\n", sid_string_static(&gnop.out.sids[i].sid), gsop.out.sids[i].name);
+ }
+
+done:
+
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
+ fprintf(stderr, "Could not close LSA policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ fprintf(stdout, "Closed Policy handle.\n");
+ }
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/lsa/lsaenum.c b/examples/libmsrpc/test/lsa/lsaenum.c
new file mode 100644
index 0000000000..d4ad4f73aa
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsaenum.c
@@ -0,0 +1,96 @@
+/*enumerates SIDs*/
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+int main(int argc, char **argv) {
+
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ POLICY_HND *pol = NULL;
+
+ int i;
+ int max_sids;
+
+ mem_ctx = talloc_init("lsaenum");
+
+ hnd = cac_NewServerHandle(True);
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("How many sids do you want to grab at a time? ");
+ fscanf(stdin, "%d", &max_sids);
+
+ struct LsaOpenPolicy lop;
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ lop.in.security_qos = True;
+
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not open policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ pol = lop.out.pol;
+
+
+ struct LsaEnumSids esop;
+ ZERO_STRUCT(esop);
+ esop.in.pol = pol;
+ /*grab a couple at a time to demonstrate multiple calls*/
+ esop.in.pref_max_sids = max_sids;
+
+ printf("Attempting to fetch SIDs %d at a time\n", esop.in.pref_max_sids);
+
+ while(cac_LsaEnumSids(hnd, mem_ctx, &esop)) {
+
+ printf("\nEnumerated %d sids: \n", esop.out.num_sids);
+ for(i = 0; i < esop.out.num_sids; i++) {
+ printf(" SID: %s\n", sid_string_static(&esop.out.sids[i]));
+ }
+
+ printf("Resolving names\n");
+
+ struct LsaGetNamesFromSids gnop;
+ ZERO_STRUCT(gnop);
+
+ gnop.in.pol = pol;
+ gnop.in.sids = esop.out.sids;
+ gnop.in.num_sids = esop.out.num_sids;
+
+ if(!cac_LsaGetNamesFromSids(hnd, mem_ctx, &gnop)) {
+ fprintf(stderr, "Could not resolve names.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("\nResolved %d names: \n", gnop.out.num_found);
+ for(i = 0; i < gnop.out.num_found; i++) {
+ printf(" SID: %s\n", sid_string_static(&gnop.out.sids[i].sid));
+ printf(" Name: %s\n", gnop.out.sids[i].name);
+ }
+
+ /*clean up a little*/
+ talloc_free(gnop.out.sids);
+ }
+
+done:
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, pol)) {
+ fprintf(stderr, "Could not close policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/lsa/lsaenumprivs.c b/examples/libmsrpc/test/lsa/lsaenumprivs.c
new file mode 100644
index 0000000000..8b5c9deca6
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsaenumprivs.c
@@ -0,0 +1,79 @@
+/*enumerates privileges*/
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+#define MAX_STRING_LEN 50;
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+ POLICY_HND *lsa_pol = NULL;
+
+ int i;
+
+ mem_ctx = talloc_init("lsatrust");
+
+ hnd = cac_NewServerHandle(True);
+
+ printf("Server: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("Connecting to server....\n");
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s\n errno %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("Connected to server\n");
+
+ struct LsaOpenPolicy lop;
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ lop.in.security_qos = True;
+
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not open policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ lsa_pol = lop.out.pol;
+
+ printf("Enumerating Privileges\n");
+
+ struct LsaEnumPrivileges ep;
+ ZERO_STRUCT(ep);
+
+ ep.in.pol = lsa_pol;
+ ep.in.pref_max_privs = 50;
+
+ while(cac_LsaEnumPrivileges(hnd, mem_ctx, &ep)) {
+ printf(" Enumerated %d privileges\n", ep.out.num_privs);
+
+ for(i = 0; i < ep.out.num_privs; i++) {
+ printf("\"%s\"\n", ep.out.priv_names[i]);
+ }
+
+ printf("\n");
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Error while enumerating privileges.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+done:
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
+ fprintf(stderr, "Could not close policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/lsa/lsapol.c b/examples/libmsrpc/test/lsa/lsapol.c
new file mode 100644
index 0000000000..58407e4343
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsapol.c
@@ -0,0 +1,87 @@
+/* simple test code, opens and closes an LSA policy handle using libmsrpc, careful.. there's no password input masking*/
+
+#include "includes.h"
+#include "libmsrpc.h"
+
+void fill_conn_info(CacServerHandle *hnd) {
+ pstring domain;
+ pstring username;
+ pstring password;
+ pstring server;
+
+ fprintf(stdout, "Enter domain name: ");
+ fscanf(stdin, "%s", domain);
+
+ fprintf(stdout, "Enter username: ");
+ fscanf(stdin, "%s", username);
+
+ fprintf(stdout, "Enter password (no input masking): ");
+ fscanf(stdin, "%s", password);
+
+ fprintf(stdout, "Enter server (ip or name): ");
+ fscanf(stdin, "%s", server);
+
+ hnd->domain = SMB_STRDUP(domain);
+ hnd->username = SMB_STRDUP(username);
+ hnd->password = SMB_STRDUP(password);
+ hnd->server = SMB_STRDUP(server);
+}
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx;
+ struct LsaOpenPolicy op;
+
+ mem_ctx = talloc_init("lsapol");
+
+
+ hnd = cac_NewServerHandle(False);
+
+ /*this line is unnecesary*/
+ cac_SetAuthDataFn(hnd, cac_GetAuthDataFn);
+
+ hnd->debug = 0;
+
+ fill_conn_info(hnd);
+
+ /*connect to the server, its name/ip is already in the handle so just pass NULL*/
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server. \n Error %s\n errno(%d): %s\n", nt_errstr(hnd->status), errno, strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+ else {
+ fprintf(stdout, "Connected to server\n");
+ }
+
+ op.in.access = GENERIC_EXECUTE_ACCESS;
+ op.in.security_qos = True;
+
+ /*open the handle*/
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &op)) {
+ fprintf(stderr, "Could not open policy.\n Error: %s.errno: %d.\n", nt_errstr(hnd->status), errno);
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+ else {
+ fprintf(stdout, "Opened Policy handle\n");
+ }
+
+ /*close the handle*/
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, op.out.pol)) {
+ fprintf(stderr, "Could not close policy. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ fprintf(stdout, "Closed Policy handle\n");
+ }
+
+ /*cleanup*/
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ fprintf(stdout, "Free'd server handle\n");
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/lsa/lsapriv.c b/examples/libmsrpc/test/lsa/lsapriv.c
new file mode 100644
index 0000000000..80b3ea102f
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsapriv.c
@@ -0,0 +1,113 @@
+/*tries to set privileges for an account*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+#define BIGGEST_UINT32 0xffffffff
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ struct LsaOpenPolicy lop;
+ struct LsaEnumPrivileges ep;
+ struct LsaEnumAccountRights ar;
+ struct LsaAddPrivileges ap;
+
+ fstring tmp;
+
+ uint32 i = 0;
+
+ mem_ctx = talloc_init("lsapriv");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not open LSA policy. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ /*first enumerate possible privileges*/
+ ZERO_STRUCT(ep);
+
+ ep.in.pol = lop.out.pol;
+ ep.in.pref_max_privs = BIGGEST_UINT32;
+
+ printf("Enumerating supported privileges:\n");
+ while(cac_LsaEnumPrivileges(hnd, mem_ctx, &ep)) {
+ for(i = 0; i < ep.out.num_privs; i++) {
+ printf("\t%s\n", ep.out.priv_names[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Could not enumerate privileges. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Enter account name: ");
+ cactest_readline(stdin, tmp);
+
+ ZERO_STRUCT(ar);
+
+ ar.in.pol = lop.out.pol;
+ ar.in.name = talloc_strdup(mem_ctx, tmp);
+
+ printf("Enumerating privileges for %s:\n", ar.in.name);
+ if(!cac_LsaEnumAccountRights(hnd, mem_ctx, &ar)) {
+ fprintf(stderr, "Could not enumerate privileges. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Enumerated %d privileges:\n", ar.out.num_privs);
+
+ for(i = 0; i < ar.out.num_privs; i++)
+ printf("\t%s\n", ar.out.priv_names[i]);
+
+ ZERO_STRUCT(ap);
+
+ ap.in.pol = lop.out.pol;
+ ap.in.name = ar.in.name;
+
+ printf("How many privileges will you set: ");
+ scanf("%d", &ap.in.num_privs);
+
+ ap.in.priv_names = talloc_array(mem_ctx, char *, ap.in.num_privs);
+ if(!ap.in.priv_names) {
+ fprintf(stderr, "No memory\n");
+ goto done;
+ }
+
+ for(i = 0; i < ap.in.num_privs; i++) {
+ printf("Enter priv %d: ", i);
+ cactest_readline(stdin, tmp);
+
+ ap.in.priv_names[i] = talloc_strdup(mem_ctx, tmp);
+ }
+
+ if(!cac_LsaSetPrivileges(hnd, mem_ctx, &ap)) {
+ fprintf(stderr, "Could not set privileges. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+done:
+ talloc_destroy(mem_ctx);
+ cac_FreeHandle(hnd);
+
+ return 0;
+
+}
+
diff --git a/examples/libmsrpc/test/lsa/lsaq.c b/examples/libmsrpc/test/lsa/lsaq.c
new file mode 100644
index 0000000000..54c1849bfd
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsaq.c
@@ -0,0 +1,245 @@
+/* connects to an LSA, asks for a list of server names, prints out their sids, then looks up their names from the sids and prints them out again
+ * if you run as lsaq -p, then it will simulate a partial success for cac_GetNamesFromSids. It will try to lookup the server's local and domain sids
+ */
+
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+void fill_conn_info(CacServerHandle *hnd) {
+ pstring domain;
+ pstring username;
+ pstring password;
+ pstring server;
+
+ fprintf(stdout, "Enter domain name: ");
+ fscanf(stdin, "%s", domain);
+
+ fprintf(stdout, "Enter username: ");
+ fscanf(stdin, "%s", username);
+
+ fprintf(stdout, "Enter password (no input masking): ");
+ fscanf(stdin, "%s", password);
+
+ fprintf(stdout, "Enter server (ip or name): ");
+ fscanf(stdin, "%s", server);
+
+ hnd->domain = SMB_STRDUP(domain);
+ hnd->username = SMB_STRDUP(username);
+ hnd->password = SMB_STRDUP(password);
+ hnd->server = SMB_STRDUP(server);
+}
+
+void get_server_names(TALLOC_CTX *mem_ctx, int *num_names, char ***names) {
+ int i = 0;
+ pstring tmp;
+
+ fprintf(stdout, "How many names do you want to lookup?: ");
+ fscanf(stdin, "%d", num_names);
+
+ *names = TALLOC_ARRAY(mem_ctx, char *, *num_names);
+ if(*names == NULL) {
+ fprintf(stderr, "No memory for allocation\n");
+ exit(-1);
+ }
+
+ for(i = 0; i < *num_names; i++) {
+ fprintf(stdout, "Enter name: ");
+ fscanf(stdin, "%s", tmp);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ }
+}
+
+int main(int argc, char **argv) {
+ int i;
+ int result;
+ char **names;
+ int num_names;
+ int num_sids;
+ CacServerHandle *hnd = NULL;
+ POLICY_HND *lsa_pol = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DOM_SID *sid_buf = NULL;
+
+ BOOL sim_partial = False;
+
+ if(argc > 1 && strcmp(argv[1], "-p") == 0)
+ sim_partial = True;
+
+ mem_ctx = talloc_init("lsaq");
+
+ hnd = cac_NewServerHandle(False);
+
+ fill_conn_info(hnd);
+
+ get_server_names(mem_ctx, &num_names, &names);
+
+ /*connect to the PDC and open a LSA handle*/
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error %s.\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ fprintf(stdout, "Connected to server: %s\n", hnd->server);
+
+ struct LsaOpenPolicy lop;
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ lop.in.security_qos = True;
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not get lsa policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ fprintf(stdout, "Opened Policy Handle\n");
+
+ /*just to make things neater*/
+ lsa_pol = lop.out.pol;
+
+ /*fetch the local sid and domain sid for the pdc*/
+
+ struct LsaFetchSid fsop;
+ ZERO_STRUCT(fsop);
+
+ fsop.in.pol = lsa_pol;
+ fsop.in.info_class = (CAC_LOCAL_INFO|CAC_DOMAIN_INFO);
+
+ fprintf(stdout, "fetching SID info for %s\n", hnd->server);
+
+ result = cac_LsaFetchSid(hnd, mem_ctx, &fsop);
+ if(!result) {
+ fprintf(stderr, "Could not get sid for server: %s\n. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+ exit(-1);
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "could not retrieve both domain and local information\n");
+ }
+
+
+ fprintf(stdout, "Fetched SID info for %s\n", hnd->server);
+ if(fsop.out.local_sid != NULL)
+ fprintf(stdout, " domain: %s. Local SID: %s\n", fsop.out.local_sid->domain, sid_string_static(&fsop.out.local_sid->sid));
+
+ if(fsop.out.domain_sid != NULL)
+ fprintf(stdout, " domain: %s, Domain SID: %s\n", fsop.out.domain_sid->domain, sid_string_static(&fsop.out.domain_sid->sid));
+
+ fprintf(stdout, "\nAttempting to query info policy\n");
+
+ struct LsaQueryInfoPolicy qop;
+ ZERO_STRUCT(qop);
+
+ qop.in.pol = lsa_pol;
+
+ if(!cac_LsaQueryInfoPolicy(hnd, mem_ctx, &qop)) {
+ fprintf(stderr, "Could not query information policy!.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ fprintf(stdout, "Query result: \n");
+ fprintf(stdout, " domain name: %s\n", qop.out.domain_name);
+ fprintf(stdout, " dns name: %s\n", qop.out.dns_name);
+ fprintf(stdout, " forest name: %s\n", qop.out.forest_name);
+ fprintf(stdout, " domain guid: %s\n", smb_uuid_string_static(*qop.out.domain_guid));
+ fprintf(stdout, " domain sid: %s\n", sid_string_static(qop.out.domain_sid));
+
+ fprintf(stdout, "\nLooking up sids\n");
+
+ struct LsaGetSidsFromNames gsop;
+ ZERO_STRUCT(gsop);
+
+ gsop.in.pol = lsa_pol;
+ gsop.in.num_names = num_names;
+ gsop.in.names = names;
+
+ result = cac_LsaGetSidsFromNames(hnd, mem_ctx, &gsop);
+
+ if(!result) {
+ fprintf(stderr, "Could not lookup any sids!\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "Not all names could be looked up.\nThe following names were not found:\n");
+
+ for(i = 0; i < (num_names - gsop.out.num_found); i++) {
+ fprintf(stdout, " %s\n", gsop.out.unknown[i]);
+ }
+
+ fprintf(stdout, "\n");
+ }
+
+ /*buffer the sids so we can look them up back to names*/
+ num_sids = (sim_partial) ? gsop.out.num_found + 2: gsop.out.num_found;
+ sid_buf = TALLOC_ARRAY(mem_ctx, DOM_SID, num_sids);
+
+ fprintf(stdout, "%d names were resolved: \n", gsop.out.num_found);
+
+
+ i = 0;
+ while(i < gsop.out.num_found) {
+ fprintf(stdout, " Name: %s\n SID: %s\n\n", gsop.out.sids[i].name, sid_string_static(&gsop.out.sids[i].sid));
+
+ sid_buf[i] = gsop.out.sids[i].sid;
+
+ i++;
+ }
+
+ /*if we want a partial success to occur below, then add the server's SIDs to the end of the array*/
+ if(sim_partial) {
+ sid_buf[i] = fsop.out.local_sid->sid;
+ sid_buf[i+1] = fsop.out.domain_sid->sid;
+ }
+
+ fprintf(stdout, "Looking up Names from SIDs\n");
+
+ struct LsaGetNamesFromSids gnop;
+ ZERO_STRUCT(gnop);
+
+ gnop.in.pol = lsa_pol;
+ gnop.in.num_sids = num_sids;
+ gnop.in.sids = sid_buf;
+
+ result = cac_LsaGetNamesFromSids(hnd, mem_ctx, &gnop);
+
+ if(!result) {
+ fprintf(stderr, "Could not lookup any names!.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(result == CAC_PARTIAL_SUCCESS) {
+ fprintf(stdout, "\nNot all SIDs could be looked up.\n. The following SIDs were not found:\n");
+
+ for(i = 0; i < (num_sids - gnop.out.num_found); i++) {
+ fprintf(stdout, "SID: %s\n", sid_string_static(&gnop.out.unknown[i]));
+ }
+
+ fprintf(stdout, "\n");
+ }
+
+ fprintf(stdout, "%d SIDs were resolved: \n", gnop.out.num_found);
+ for(i = 0; i < gnop.out.num_found; i++) {
+ fprintf(stdout, " SID: %s\n Name: %s\n", sid_string_static(&gnop.out.sids[i].sid), gsop.out.sids[i].name);
+ }
+
+done:
+
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
+ fprintf(stderr, "Could not close LSA policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ fprintf(stdout, "Closed Policy handle.\n");
+ }
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/lsa/lsatrust.c b/examples/libmsrpc/test/lsa/lsatrust.c
new file mode 100644
index 0000000000..6ad293f832
--- /dev/null
+++ b/examples/libmsrpc/test/lsa/lsatrust.c
@@ -0,0 +1,151 @@
+/*queries trusted domain information*/
+
+#include "libmsrpc.h"
+#include "includes.h"
+
+#define MAX_STRING_LEN 50;
+
+void print_info(LSA_TRUSTED_DOMAIN_INFO *info) {
+ switch(info->info_class) {
+ case CAC_INFO_TRUSTED_DOMAIN_FULL_INFO:
+ case CAC_INFO_TRUSTED_DOMAIN_INFO_ALL:
+ printf(" Domain Name: %s\n", unistr2_static(&info->info_ex.domain_name.unistring));
+ printf(" Netbios Name: %s\n", unistr2_static(&info->info_ex.netbios_name.unistring));
+ printf(" Domain Sid: %s\n", sid_string_static(&info->info_ex.sid.sid));
+ printf(" Trust direction: %d\n", info->info_ex.trust_direction);
+ printf(" Trust Type: %d\n", info->info_ex.trust_type);
+ printf(" Trust attr: %d\n", info->info_ex.trust_attributes);
+ printf(" Posix Offset: %d\n", info->posix_offset.posix_offset);
+ break;
+ }
+}
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+ POLICY_HND *lsa_pol = NULL;
+
+ int i;
+
+ mem_ctx = talloc_init("lsatrust");
+
+ hnd = cac_NewServerHandle(False);
+
+ /*malloc some memory so get_auth_data_fn can work*/
+ hnd->username = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->domain = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->netbios_name = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->password = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+
+ hnd->server = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+
+
+ printf("Server: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("Connecting to server....\n");
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s\n errno %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("Connected to server\n");
+
+ struct LsaOpenPolicy lop;
+ ZERO_STRUCT(lop);
+
+ lop.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+ lop.in.security_qos = True;
+
+
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop)) {
+ fprintf(stderr, "Could not open policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ lsa_pol = lop.out.pol;
+
+ printf("Enumerating Trusted Domains\n");
+
+ struct LsaEnumTrustedDomains etd;
+ ZERO_STRUCT(etd);
+
+ etd.in.pol = lsa_pol;
+
+ while(cac_LsaEnumTrustedDomains(hnd, mem_ctx, &etd)) {
+ printf(" Enumerated %d domains\n", etd.out.num_domains);
+
+ for(i = 0; i < etd.out.num_domains; i++) {
+ printf(" Name: %s\n", etd.out.domain_names[i]);
+ printf(" SID: %s\n", sid_string_static(&etd.out.domain_sids[i]));
+
+ printf("\n Attempting to open domain...\n");
+
+ struct LsaOpenTrustedDomain otd;
+ ZERO_STRUCT(otd);
+
+ otd.in.pol = lsa_pol;
+ otd.in.domain_sid = &etd.out.domain_sids[i];
+ otd.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+
+ /*try to query trusted domain info by name*/
+ struct LsaQueryTrustedDomainInfo qtd;
+ ZERO_STRUCT(qtd);
+
+ qtd.in.pol = lsa_pol;
+ qtd.in.domain_name = etd.out.domain_names[i];
+
+
+ int j;
+ for(j = 0; j < 100; j++ ) {
+ qtd.in.info_class = j;
+
+ printf(" Querying trustdom by name\n");
+ if(!cac_LsaQueryTrustedDomainInfo(hnd, mem_ctx, &qtd)) {
+ fprintf(stderr, " could not query trusted domain info.\n Error %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf(" info_class %d succeeded\n", j);
+ printf(" Query result:\n");
+ printf(" size %d\n", sizeof(*qtd.out.info));
+ }
+
+ /*try to query trusted domain info by SID*/
+ printf(" Querying trustdom by sid\n");
+ qtd.in.domain_sid = &etd.out.domain_sids[i];
+ if(!cac_LsaQueryTrustedDomainInfo(hnd, mem_ctx, &qtd)) {
+ fprintf(stderr, " could not query trusted domain info.\n Error %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf(" Query result:\n");
+/* print_info(qtd.out.info);*/
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, " Could not enum sids.\n Error: %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+ }
+
+ printf("\n");
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Error while enumerating trusted domains.\n Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+done:
+ if(!cac_LsaClosePolicy(hnd, mem_ctx, lsa_pol)) {
+ fprintf(stderr, "Could not close policy handle.\n Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/reg/regdelete.c b/examples/libmsrpc/test/reg/regdelete.c
new file mode 100644
index 0000000000..50b08ba468
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regdelete.c
@@ -0,0 +1,102 @@
+/*tests deleting a key or value*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring tmp;
+ char input = 'v';
+
+ mem_ctx = talloc_init("regdelete");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ printf("enter key to open: \n");
+ cactest_readline(stdin, tmp);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.name = talloc_strdup(mem_ctx, tmp);
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s. Error %s\n", rok.in.name, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ printf("getting version (just for testing\n");
+
+ struct RegGetVersion rgv;
+ ZERO_STRUCT(rgv);
+
+ rgv.in.key = rok.out.key;
+
+ if(!cac_RegGetVersion(hnd, mem_ctx, &rgv))
+ fprintf(stderr, "Could not get version. Error: %s\n", nt_errstr(hnd->status));
+ else
+ printf("Version: %d\n", rgv.out.version);
+
+
+ while(input == 'v' || input == 'k') {
+ printf("Delete [v]alue [k]ey or [q]uit: ");
+ scanf("%c", &input);
+
+ switch(input) {
+ case 'v':
+ printf("Value to delete: ");
+ cactest_readline(stdin, tmp);
+
+ struct RegDeleteValue rdv;
+ ZERO_STRUCT(rdv);
+
+ rdv.in.parent_key = rok.out.key;
+ rdv.in.name = talloc_strdup(mem_ctx, tmp);
+
+ if(!cac_RegDeleteValue(hnd, mem_ctx, &rdv))
+ fprintf(stderr, "Could not delete value %s. Error: %s\n", rdv.in.name, nt_errstr(hnd->status));
+
+ break;
+ case 'k':
+ printf("Key to delete: ");
+ cactest_readline(stdin, tmp);
+
+ struct RegDeleteKey rdk;
+ ZERO_STRUCT(rdk);
+
+ rdk.in.parent_key = rok.out.key;
+ rdk.in.name = talloc_strdup(mem_ctx, tmp);
+
+ printf("delete recursively? [y/n]: ");
+ cactest_readline(stdin, tmp);
+
+ rdk.in.recursive = (tmp[0] == 'y') ? True : False;
+
+ if(!cac_RegDeleteKey(hnd, mem_ctx, &rdk))
+ fprintf(stderr, "Could not delete key %s. Error %s\n", rdk.in.name, nt_errstr(hnd->status));
+
+ break;
+ }
+ }
+ cac_RegClose(hnd, mem_ctx, rok.out.key);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
+
diff --git a/examples/libmsrpc/test/reg/regkey.c b/examples/libmsrpc/test/reg/regkey.c
new file mode 100644
index 0000000000..a90d06c6ef
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regkey.c
@@ -0,0 +1,76 @@
+/*opens and closes a key*/
+
+#include "libmsrpc.h"
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring key;
+
+ mem_ctx = talloc_init("regkey");
+
+ hnd = cac_NewServerHandle(False);
+
+ /*allocate some memory so get_auth_data_fn can do it's magic*/
+ hnd->username = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->domain = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->netbios_name = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+ hnd->password = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+
+ hnd->server = SMB_MALLOC_ARRAY(char, sizeof(fstring));
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ struct RegConnect rc;
+ ZERO_STRUCT(rc);
+
+ rc.in.access = REG_KEY_ALL;
+ rc.in.root = HKEY_LOCAL_MACHINE;
+
+ if(!cac_RegConnect(hnd, mem_ctx, &rc)) {
+ fprintf(stderr, " Could not connect to registry. %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("trying to open key %s...\n", key);
+
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = rc.out.key;
+ rok.in.name = key;
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+
+ if(!cac_RegClose(hnd, mem_ctx, rc.out.key)) {
+ fprintf(stderr, " Could not close handle. %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regkeycreate.c b/examples/libmsrpc/test/reg/regkeycreate.c
new file mode 100644
index 0000000000..50764f1682
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regkeycreate.c
@@ -0,0 +1,115 @@
+/*tests creating a registry key*/
+
+#include "libmsrpc.h"
+
+#define MAX_KEYS_PER_ENUM 3
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring key_name;
+
+ fstring key_to_create;
+
+ mem_ctx = talloc_init("regcreatekey");
+
+ hnd = cac_NewServerHandle(True);
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key_name);
+
+ printf("Enter key to create: ");
+ fscanf(stdin, "%s", key_to_create);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("trying to open key %s...\n", key_name);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = NULL;
+ rok.in.name = key_name;
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Creating key %s...\n", key_to_create);
+
+ struct RegCreateKey rck;
+ ZERO_STRUCT(rck);
+
+ rck.in.parent_key = rok.out.key;
+ rck.in.key_name = talloc_strdup(mem_ctx, key_to_create);
+ rck.in.class_name = talloc_strdup(mem_ctx, "");
+ rck.in.access = REG_KEY_ALL;
+
+ if(!cac_RegCreateKey(hnd, mem_ctx, &rck)) {
+ fprintf(stderr, "Could not create key. Error %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ if(!cac_RegClose(hnd, mem_ctx, rck.out.key)) {
+ fprintf(stderr, "Could not close key. Error %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ /**enumerate all the subkeys*/
+ printf("Enumerating all subkeys:\n");
+
+ struct RegEnumKeys ek;
+ ZERO_STRUCT(ek);
+
+ ek.in.key = rok.out.key;
+ ek.in.max_keys = 50;
+
+ while(cac_RegEnumKeys(hnd, mem_ctx, &ek)) {
+ int j;
+
+ for(j = 0; j < ek.out.num_keys; j++) {
+ printf(" Key name: %s\n", ek.out.key_names[j]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Could not enumerate keys: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("deleting key %s\n", key_to_create);
+
+ struct RegDeleteKey rdk;
+ ZERO_STRUCT(rdk);
+
+ rdk.in.parent_key = rok.out.key;
+ rdk.in.name = key_to_create;
+
+ if(!cac_RegDeleteKey(hnd, mem_ctx, &rdk)) {
+ fprintf(stderr, "Could not delete key. Error %s\n", nt_errstr(hnd->status));
+ }
+
+ printf("closing key %s...\n", key_name);
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regkeyenum.c b/examples/libmsrpc/test/reg/regkeyenum.c
new file mode 100644
index 0000000000..f140d95723
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regkeyenum.c
@@ -0,0 +1,99 @@
+/*tests enumerating keys or values*/
+
+#include "libmsrpc.h"
+
+#define MAX_KEYS_PER_ENUM 3
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ int num_keys;
+
+ int max_enum;
+
+ int i;
+
+ fstring *key_names;
+
+ mem_ctx = talloc_init("regkeyenum");
+
+ hnd = cac_NewServerHandle(True);
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("How many keys do you want to open?: ");
+ fscanf(stdin, "%d", &num_keys);
+
+ printf("How many keys per enum?: ");
+ fscanf(stdin, "%d", &max_enum);
+
+ key_names = TALLOC_ARRAY(mem_ctx, fstring , num_keys);
+ if(!key_names) {
+ fprintf(stderr, "No memory\n");
+ exit(-1);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key_names[i]);
+ }
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("trying to open key %s...\n", key_names[i]);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = NULL;
+ rok.in.name = key_names[i];
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ continue;
+ }
+
+ /**enumerate all the subkeys*/
+ printf("Enumerating all subkeys:\n");
+
+ struct RegEnumKeys ek;
+ ZERO_STRUCT(ek);
+
+ ek.in.key = rok.out.key;
+ ek.in.max_keys = max_enum;
+
+ while(cac_RegEnumKeys(hnd, mem_ctx, &ek)) {
+ int j;
+
+ for(j = 0; j < ek.out.num_keys; j++) {
+ printf(" Key name: %s\n", ek.out.key_names[j]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Could not enumerate keys: %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf("closing key %s...\n", key_names[i]);
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+ }
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regopen.c b/examples/libmsrpc/test/reg/regopen.c
new file mode 100644
index 0000000000..fedc52e40d
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regopen.c
@@ -0,0 +1,66 @@
+/*opens and closes a registry handle*/
+
+#include "libmsrpc.h"
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ POLICY_HND **keys = NULL;
+
+ char roots[4][50] = { {CAC_HKCR}, {CAC_HKLM}, {CAC_HKU}, {CAC_HKPD} };
+
+ int i;
+
+
+ mem_ctx = talloc_init("regopen");
+
+ hnd = cac_NewServerHandle(True);
+
+ keys = TALLOC_ARRAY(mem_ctx, POLICY_HND *, 4);
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ struct RegConnect rc;
+ ZERO_STRUCT(rc);
+
+ rc.in.access = SEC_RIGHT_MAXIMUM_ALLOWED;
+
+ for(i = 0; i < 4; i++) {
+ printf("opening: %s\n", roots[i]);
+
+ rc.in.root = roots[i];
+
+ if(!cac_RegConnect(hnd, mem_ctx, &rc)) {
+ fprintf(stderr, " Could not connect to registry. %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ keys[i] = rc.out.key;
+ }
+
+ for(i = 3; i >= 0; i--) {
+ if(keys[i] == NULL)
+ continue;
+
+ printf("closing: %s\n", roots[i]);
+
+ if(!cac_RegClose(hnd, mem_ctx, keys[i])) {
+ fprintf(stderr, " Could not close handle. %s\n", nt_errstr(hnd->status));
+ }
+ }
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regopenkey.c b/examples/libmsrpc/test/reg/regopenkey.c
new file mode 100644
index 0000000000..732da17ccf
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regopenkey.c
@@ -0,0 +1,69 @@
+/*tests cac_RegOpenKey()*/
+
+#include "libmsrpc.h"
+
+int main() {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ int num_keys;
+ int i;
+
+ fstring *key_names;
+
+ mem_ctx = talloc_init("regopenkey");
+
+ hnd = cac_NewServerHandle(True);
+
+ printf("Enter server to connect to: ");
+ fscanf(stdin, "%s", hnd->server);
+
+ printf("How many keys do you want to open?: ");
+ fscanf(stdin, "%d", &num_keys);
+
+ key_names = TALLOC_ARRAY(mem_ctx, fstring , num_keys);
+ if(!key_names) {
+ fprintf(stderr, "No memory\n");
+ exit(-1);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key_names[i]);
+ }
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("trying to open key %s...\n", key_names[i]);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = NULL;
+ rok.in.name = key_names[i];
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf("closing key %s...\n", key_names[i]);
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+ }
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regqueryval.c b/examples/libmsrpc/test/reg/regqueryval.c
new file mode 100644
index 0000000000..9989651898
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regqueryval.c
@@ -0,0 +1,79 @@
+/*tests cac_RegQueryValue()*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+#define MAX_KEYS_PER_ENUM 3
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring key_name;
+
+ fstring val_name;
+
+ mem_ctx = talloc_init("regqueryval");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key_name);
+
+ printf("Enter value to query: ");
+ fscanf(stdin, "%s", val_name);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("trying to open key %s...\n", key_name);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = NULL;
+ rok.in.name = key_name;
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ goto done;
+ }
+
+ struct RegQueryValue rqv;
+ ZERO_STRUCT(rqv);
+
+ rqv.in.key = rok.out.key;
+ rqv.in.val_name = talloc_strdup(mem_ctx, val_name);
+
+ printf("querying value %s...\n", rqv.in.val_name);
+ if(!cac_RegQueryValue(hnd, mem_ctx, &rqv)) {
+ fprintf(stderr, "Could not query value. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Queried value %s\n", rqv.in.val_name);
+ print_value(rqv.out.type, rqv.out.data);
+ }
+
+
+ printf("closing key %s...\n", key_name);
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/regsetval.c b/examples/libmsrpc/test/reg/regsetval.c
new file mode 100644
index 0000000000..e7327910c2
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regsetval.c
@@ -0,0 +1,59 @@
+/*tests cac_RegSetVal()*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring tmp;
+
+ mem_ctx = talloc_init("regsetval");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ printf("enter key to open: \n");
+ scanf("%s", tmp);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.name = talloc_strdup(mem_ctx, tmp);
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s. Error %s\n", rok.in.name, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct RegSetValue rsv;
+ ZERO_STRUCT(rsv);
+
+ rsv.in.key = rok.out.key;
+
+ cactest_reg_input_val(mem_ctx, &rsv.in.type, &rsv.in.val_name, &rsv.in.value);
+
+ if(!cac_RegSetValue(hnd, mem_ctx, &rsv)) {
+ fprintf(stderr, "Could not set value. Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ cac_RegClose(hnd, mem_ctx, rok.out.key);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
+
diff --git a/examples/libmsrpc/test/reg/regvalenum.c b/examples/libmsrpc/test/reg/regvalenum.c
new file mode 100644
index 0000000000..9778f4e2b3
--- /dev/null
+++ b/examples/libmsrpc/test/reg/regvalenum.c
@@ -0,0 +1,103 @@
+/*tests enumerating registry values*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+#define MAX_KEYS_PER_ENUM 3
+
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ int num_keys;
+
+ int max_enum;
+
+ fstring *key_names;
+
+ int i;
+
+ mem_ctx = talloc_init("regvalenum");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server.\n Error: %s.\n errno: %s\n", nt_errstr(hnd->status), strerror(errno));
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+ printf("How many keys do you want to open?: ");
+ fscanf(stdin, "%d", &num_keys);
+
+ printf("How many values per enum?: ");
+ fscanf(stdin, "%d", &max_enum);
+
+ key_names = TALLOC_ARRAY(mem_ctx, fstring , num_keys);
+ if(!key_names) {
+ fprintf(stderr, "No memory\n");
+ exit(-1);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("Enter key to open: ");
+ fscanf(stdin, "%s", key_names[i]);
+ }
+
+ for(i = 0; i < num_keys; i++) {
+ printf("trying to open key %s...\n", key_names[i]);
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ rok.in.parent_key = NULL;
+ rok.in.name = key_names[i];
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s\n Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ continue;
+ }
+
+ /**enumerate all the subkeys*/
+ printf("Enumerating all values:\n");
+
+ struct RegEnumValues rev;
+ ZERO_STRUCT(rev);
+
+ rev.in.key = rok.out.key;
+ rev.in.max_values = max_enum;
+
+ while(cac_RegEnumValues(hnd, mem_ctx, &rev)) {
+ int j;
+
+ for(j = 0; j < rev.out.num_values; j++) {
+ printf(" Value name: %s\n", rev.out.value_names[j]);
+ print_value(rev.out.types[j], rev.out.values[j]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ fprintf(stderr, "Could not enumerate values: %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf("closing key %s...\n", key_names[i]);
+
+ if(!cac_RegClose(hnd, mem_ctx, rok.out.key)) {
+ fprintf(stderr, "Could not close handle %s\n", nt_errstr(hnd->status));
+ }
+ }
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+
+}
diff --git a/examples/libmsrpc/test/reg/security.c b/examples/libmsrpc/test/reg/security.c
new file mode 100644
index 0000000000..6808f8c1f3
--- /dev/null
+++ b/examples/libmsrpc/test/reg/security.c
@@ -0,0 +1,74 @@
+/*tests cac_RegSetKeySecurity()*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring tmp;
+
+ mem_ctx = talloc_init("regsetval");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct RegOpenKey rok;
+ ZERO_STRUCT(rok);
+
+ printf("enter key to query: ");
+ cactest_readline(stdin, tmp);
+
+ rok.in.name = talloc_strdup(mem_ctx, tmp);
+ rok.in.access = REG_KEY_ALL;
+
+ if(!cac_RegOpenKey(hnd, mem_ctx, &rok)) {
+ fprintf(stderr, "Could not open key %s. Error %s\n", rok.in.name, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct RegGetKeySecurity rks;
+ ZERO_STRUCT(rks);
+
+ rks.in.key = rok.out.key;
+ rks.in.info_type = ALL_SECURITY_INFORMATION;
+
+ if(!cac_RegGetKeySecurity(hnd, mem_ctx, &rks)) {
+ fprintf(stderr, "Could not query security for %s. Error: %s\n", rok.in.name, nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("resetting key security...\n");
+
+ struct RegSetKeySecurity rss;
+ ZERO_STRUCT(rss);
+
+ rss.in.key = rok.out.key;
+ rss.in.info_type = ALL_SECURITY_INFORMATION;
+ rss.in.size = rks.out.size;
+ rss.in.descriptor = rks.out.descriptor;
+
+ if(!cac_RegSetKeySecurity(hnd, mem_ctx, &rss)) {
+ fprintf(stderr, "Could not set security. Error %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_RegClose(hnd, mem_ctx, rok.out.key);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
+
diff --git a/examples/libmsrpc/test/reg/shutdown.c b/examples/libmsrpc/test/reg/shutdown.c
new file mode 100644
index 0000000000..6184fbd976
--- /dev/null
+++ b/examples/libmsrpc/test/reg/shutdown.c
@@ -0,0 +1,68 @@
+/*tries to shut down a remote pc*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring tmp;
+
+ mem_ctx = talloc_init("cac_shutdown");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ hnd->_internal.srv_level = SRV_WIN_NT4;
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct Shutdown s;
+ ZERO_STRUCT(s);
+
+ printf("Message: ");
+ cactest_readline(stdin, tmp);
+
+ s.in.message = talloc_strdup(mem_ctx, tmp);
+
+ printf("timeout: ");
+ scanf("%d", &s.in.timeout);
+
+ printf("Reboot? [y/n]: ");
+ cactest_readline(stdin, tmp);
+
+ s.in.reboot = ( tmp[0] == 'y') ? True : False;
+
+ printf("Force? [y/n]: ");
+ cactest_readline(stdin, tmp);
+
+ s.in.force = (tmp[0] == 'y') ? True : False;
+
+ if(!cac_Shutdown(hnd, mem_ctx, &s)) {
+ fprintf(stderr, "could not shut down server: error %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Server %s is shutting down. Would you like to try to abort? [y/n]: ", hnd->server);
+ fscanf(stdin, "%s", tmp);
+
+ if(tmp[0] == 'y') {
+ if(!cac_AbortShutdown(hnd, mem_ctx)) {
+ fprintf(stderr, "Could not abort shutdown. Error %s\n", nt_errstr(hnd->status));
+ }
+ }
+
+done:
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/sam/adduser.c b/examples/libmsrpc/test/sam/adduser.c
new file mode 100644
index 0000000000..94482d0704
--- /dev/null
+++ b/examples/libmsrpc/test/sam/adduser.c
@@ -0,0 +1,92 @@
+/*add's a user to a domain*/
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ fstring tmp;
+
+ struct SamOpenUser ou;
+
+ POLICY_HND *user_hnd = NULL;
+
+ mem_ctx = talloc_init("cac_adduser");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ struct SamCreateUser cdu;
+ ZERO_STRUCT(cdu);
+
+ printf("Enter account name: ");
+ cactest_readline(stdin, tmp);
+
+ cdu.in.dom_hnd = sod.out.dom_hnd;
+ cdu.in.name = talloc_strdup(mem_ctx, tmp);
+ cdu.in.acb_mask = ACB_NORMAL;
+
+ if(!cac_SamCreateUser(hnd, mem_ctx, &cdu)) {
+ fprintf(stderr, "Could not create user %s. Error: %s\n", cdu.in.name, nt_errstr(hnd->status));
+ }
+
+ printf("would you like to delete this user? [y/n]: ");
+ cactest_readline(stdin, tmp);
+
+ if(tmp[0] == 'y') {
+
+ if(!cdu.out.user_hnd) {
+ ZERO_STRUCT(ou);
+ ou.in.dom_hnd = sod.out.dom_hnd;
+ ou.in.access = MAXIMUM_ALLOWED_ACCESS;
+ ou.in.name = talloc_strdup(mem_ctx, cdu.in.name);
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
+ fprintf(stderr, "Could not open user for deletion. Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ user_hnd = ou.out.user_hnd;
+ }
+
+ else {
+ user_hnd = cdu.out.user_hnd;
+ }
+
+ if(!cac_SamDeleteUser(hnd, mem_ctx, user_hnd))
+ fprintf(stderr, "Could not delete user. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Nope..ok\n");
+ }
+
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+ cac_SamClose(hnd, mem_ctx, sod.out.sam);
+
+done:
+ talloc_destroy(mem_ctx);
+
+ cac_FreeHandle(hnd);
+
+ return 0;
+}
+
+/*TODO: add a function that will create a user and set userinfo and set the password*/
diff --git a/examples/libmsrpc/test/sam/disable.c b/examples/libmsrpc/test/sam/disable.c
new file mode 100644
index 0000000000..f140bad50b
--- /dev/null
+++ b/examples/libmsrpc/test/sam/disable.c
@@ -0,0 +1,63 @@
+/*disable a user*/
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ struct SamOpenUser ou;
+
+ fstring tmp;
+
+ mem_ctx = talloc_init("cac_disable");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ ZERO_STRUCT(ou);
+ printf("Enter username: ");
+ cactest_readline(stdin, tmp);
+
+ ou.in.name = talloc_strdup(mem_ctx, tmp);
+ ou.in.access = MAXIMUM_ALLOWED_ACCESS;
+ ou.in.dom_hnd = sod.out.dom_hnd;
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
+ fprintf(stderr, "Could not open user. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ /*enable the user*/
+ if(!cac_SamDisableUser(hnd, mem_ctx, ou.out.user_hnd)) {
+ fprintf(stderr, "Could not disable user: %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/sam/dominfo.c b/examples/libmsrpc/test/sam/dominfo.c
new file mode 100644
index 0000000000..cd2eccefba
--- /dev/null
+++ b/examples/libmsrpc/test/sam/dominfo.c
@@ -0,0 +1,55 @@
+/*gets domain info and prints it out*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ mem_ctx = talloc_init("cac_dominfo");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ struct SamGetDomainInfo gdi;
+ ZERO_STRUCT(gdi);
+
+ gdi.in.dom_hnd = sod.out.dom_hnd;
+
+ if(!cac_SamGetDomainInfo(hnd, mem_ctx, &gdi)) {
+ fprintf(stderr, "Could not get domain info. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Got domain info:\n");
+ print_cac_domain_info(gdi.out.info);
+
+done:
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/sam/enable.c b/examples/libmsrpc/test/sam/enable.c
new file mode 100644
index 0000000000..bb91fb241c
--- /dev/null
+++ b/examples/libmsrpc/test/sam/enable.c
@@ -0,0 +1,64 @@
+/*enable a user*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ struct SamOpenUser ou;
+
+ fstring tmp;
+
+ mem_ctx = talloc_init("cac_samgroup");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ ZERO_STRUCT(ou);
+ printf("Enter username: ");
+ cactest_readline(stdin, tmp);
+
+ ou.in.name = talloc_strdup(mem_ctx, tmp);
+ ou.in.access = MAXIMUM_ALLOWED_ACCESS;
+ ou.in.dom_hnd = sod.out.dom_hnd;
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
+ fprintf(stderr, "Could not open user. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ /*enable the user*/
+ if(!cac_SamEnableUser(hnd, mem_ctx, ou.out.user_hnd)) {
+ fprintf(stderr, "Could not enable user: %s\n", nt_errstr(hnd->status));
+ }
+
+done:
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/sam/samenum.c b/examples/libmsrpc/test/sam/samenum.c
new file mode 100644
index 0000000000..5b10475aac
--- /dev/null
+++ b/examples/libmsrpc/test/sam/samenum.c
@@ -0,0 +1,117 @@
+/*enumerate users/groups/aliases*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+
+ struct SamEnumUsers eu;
+ struct SamEnumGroups eg;
+ struct SamEnumAliases ea;
+
+ fstring tmp;
+
+ int i;
+
+ mem_ctx = talloc_init("cac_samenum");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ tmp[0] = 0x00;
+ while(tmp[0] != 'q') {
+ printf("Enumerate [u]sers, [g]roups or [a]liases or [q]uit: ");
+ cactest_readline(stdin, tmp);
+
+ switch(tmp[0]) {
+ case 'u':
+ ZERO_STRUCT(eu);
+
+ eu.in.dom_hnd = sod.out.dom_hnd;
+
+ printf("ACB mask (can be 0): ");
+ scanf("%hx", &eu.in.acb_mask);
+
+ while(cac_SamEnumUsers(hnd, mem_ctx, &eu)) {
+ printf("Enumerated %d users:\n", eu.out.num_users);
+ for(i = 0; i < eu.out.num_users; i++) {
+ printf(" Name: %s\n", eu.out.names[i]);
+ printf(" RID: %d\n", eu.out.rids[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate users. Error: %s\n", nt_errstr(hnd->status));
+ }
+ break;
+ case 'g':
+ ZERO_STRUCT(eg);
+ eg.in.dom_hnd = sod.out.dom_hnd;
+
+ printf("Enumerating groups...\n");
+ while(cac_SamEnumGroups(hnd, mem_ctx, &eg)) {
+ printf("Enumerated %d groups:\n", eg.out.num_groups);
+ for(i = 0; i < eg.out.num_groups; i++) {
+ printf("RID: %d\n", eg.out.rids[i]);
+ printf("Name: %s\n", eg.out.names[i]);
+ printf("Desc: %s\n", eg.out.descriptions[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate Groups. Error: %s\n", nt_errstr(hnd->status));
+ }
+ break;
+ case 'a':
+ ZERO_STRUCT(ea);
+ ea.in.dom_hnd = sod.out.dom_hnd;
+
+ printf("Enumerating Aliases...\n");
+ while(cac_SamEnumAliases(hnd, mem_ctx, &ea)) {
+ printf("Enumerated %d aliases:\n", ea.out.num_aliases);
+
+ for(i = 0; i < ea.out.num_aliases; i++) {
+ printf("RID: %d\n", ea.out.rids[i]);
+ printf("Name: %s\n", ea.out.names[i]);
+ printf("Desc: %s\n", ea.out.descriptions[i]);
+ }
+ }
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate Aliases. Error: %s\n", nt_errstr(hnd->status));
+ }
+ break;
+ }
+ }
+
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+ cac_SamClose(hnd, mem_ctx, sod.out.sam);
+
+done:
+ talloc_destroy(mem_ctx);
+ cac_FreeHandle(hnd);
+
+ return 0;
+
+}
+
diff --git a/examples/libmsrpc/test/sam/samgroup.c b/examples/libmsrpc/test/sam/samgroup.c
new file mode 100644
index 0000000000..39d9fa1137
--- /dev/null
+++ b/examples/libmsrpc/test/sam/samgroup.c
@@ -0,0 +1,480 @@
+/*Some group management stuff*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+
+ struct SamEnumGroups eg;
+ struct SamEnumUsers eu;
+ struct SamCreateGroup cg;
+ struct SamOpenGroup og;
+ struct SamGetGroupMembers ggm;
+ struct SamGetNamesFromRids gn;
+ struct SamAddGroupMember add;
+ struct SamRemoveGroupMember del;
+ struct SamSetGroupMembers set;
+ struct SamGetGroupsForUser gg;
+ struct SamOpenUser ou;
+ struct SamGetGroupInfo gi;
+ struct SamSetGroupInfo si;
+ struct SamRenameGroup rg;
+ struct SamGetSecurityObject gso;
+
+ POLICY_HND *group_hnd = NULL;
+
+ fstring tmp;
+ fstring input;
+
+ int i;
+
+ mem_ctx = talloc_init("cac_samgroup");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ tmp[0] = 0x00;
+ while(tmp[0] != 'q') {
+ printf("\n");
+ printf("[l]ist groups\n");
+ printf("[c]reate group\n");
+ printf("[o]pen group\n");
+ printf("[d]elete group\n");
+ printf("list [m]embers\n");
+ printf("list [u]sers\n");
+ printf("list [g]roup for users\n");
+ printf("[a]dd member\n");
+ printf("[r]emove member\n");
+ printf("[x] clear members\n");
+ printf("get group [i]nfo\n");
+ printf("[e]dit group info\n");
+ printf("[s]et members\n");
+ printf("re[n]ame group\n");
+ printf("[z] close group\n");
+ printf("[t] get security info\n");
+
+ printf("[q]uit\n\n");
+ printf("Enter option: ");
+ cactest_readline(stdin, tmp);
+
+ printf("\n");
+
+ switch(tmp[0]) {
+ case 'c': /*create group*/
+ if(group_hnd != NULL) {
+ /*then we have an open handle.. close it*/
+ cac_SamClose(hnd, mem_ctx, group_hnd);
+ group_hnd = NULL;
+ }
+
+ printf("Enter group name: ");
+ cactest_readline(stdin, input);
+
+ ZERO_STRUCT(cg);
+
+ cg.in.name = talloc_strdup(mem_ctx, input);
+ cg.in.access = MAXIMUM_ALLOWED_ACCESS;
+ cg.in.dom_hnd = sod.out.dom_hnd;
+
+ if(!cac_SamCreateGroup(hnd, mem_ctx, &cg)) {
+ fprintf(stderr, "Could not create group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Created group %s\n", cg.in.name);
+
+ group_hnd = cg.out.group_hnd;
+ }
+ break;
+
+ case 'o': /*open group*/
+ if(group_hnd != NULL) {
+ /*then we have an open handle.. close it*/
+ cac_SamClose(hnd, mem_ctx, group_hnd);
+ group_hnd = NULL;
+ }
+
+ ZERO_STRUCT(og);
+
+ og.in.dom_hnd = sod.out.dom_hnd;
+ og.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ printf("Enter RID: 0x");
+ scanf("%x", &og.in.rid);
+
+ if(!cac_SamOpenGroup(hnd, mem_ctx, &og)) {
+ fprintf(stderr, "Could not open group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Opened group\n");
+ group_hnd = og.out.group_hnd;
+ }
+
+ break;
+
+ case 'l': /*list groups*/
+ ZERO_STRUCT(eg);
+ eg.in.dom_hnd = sod.out.dom_hnd;
+
+ while(cac_SamEnumGroups(hnd, mem_ctx, &eg)) {
+ for(i = 0; i < eg.out.num_groups; i++) {
+ printf("RID: 0x%x Name: %s\n", eg.out.rids[i], eg.out.names[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate Groups. Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ break;
+
+ case 'm': /*list group members*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(ggm);
+ ggm.in.group_hnd = group_hnd;
+
+ if(!cac_SamGetGroupMembers(hnd, mem_ctx, &ggm)) {
+ fprintf(stderr, "Could not get group members. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ printf("Group has %d members:\n", ggm.out.num_members);
+
+ if(ggm.out.num_members == 0) /*just skip the rest of this case*/
+ break;
+
+ /**get the user names*/
+ gn.in.dom_hnd = sod.out.dom_hnd;
+ gn.in.num_rids = ggm.out.num_members;
+ gn.in.rids = ggm.out.rids;
+
+ if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &gn)) {
+ fprintf(stderr, "Could not lookup names. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ for(i = 0; i < gn.out.num_names; i++) {
+ printf("RID: 0x%x Name: %s\n", gn.out.map[i].rid, gn.out.map[i].name);
+ }
+
+ break;
+
+ case 'd': /*delete group*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ if(!cac_SamDeleteGroup(hnd, mem_ctx, group_hnd)) {
+ fprintf(stderr, "Could not delete group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Deleted group.\n");
+ group_hnd = NULL;
+ }
+ break;
+
+ case 'u': /*list users*/
+ ZERO_STRUCT(eu);
+
+ eu.in.dom_hnd = sod.out.dom_hnd;
+
+ while(cac_SamEnumUsers(hnd, mem_ctx, &eu)) {
+ for(i = 0; i < eu.out.num_users; i++) {
+ printf(" RID: 0x%x Name: %s\n", eu.out.rids[i], eu.out.names[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate users. Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ break;
+
+ case 'a': /*add member to group*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(add);
+
+ add.in.group_hnd = group_hnd;
+
+ printf("Enter user RID: 0x");
+ scanf("%x", &add.in.rid);
+
+ if(!cac_SamAddGroupMember(hnd, mem_ctx, &add)) {
+ fprintf(stderr, "Could not add user to group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Successfully added user to group\n");
+ }
+ break;
+
+ case 'r': /*remove user from group*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(del);
+ del.in.group_hnd = group_hnd;
+
+ printf("Enter RID: 0x");
+ scanf("%x", &del.in.rid);
+
+ if(!cac_SamRemoveGroupMember(hnd, mem_ctx, &del)) {
+ fprintf(stderr, "Could not remove user from group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Removed user from group.\n");
+ }
+
+ break;
+
+ case 'x': /*clear group members*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ if(!cac_SamClearGroupMembers(hnd, mem_ctx, group_hnd)) {
+ fprintf(stderr, "Could not clear group members. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Cleared group members\n");
+ }
+
+ break;
+
+ case 's': /*set members*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(set);
+
+ set.in.group_hnd = group_hnd;
+
+ printf("Enter the number of members: ");
+ scanf("%d", &set.in.num_members);
+
+ set.in.rids = TALLOC_ARRAY(mem_ctx, uint32, set.in.num_members);
+
+ for(i = 0; i < set.in.num_members; i++) {
+ printf("Enter RID #%d: 0x", (i+1));
+ scanf("%x", (set.in.rids + i));
+ }
+
+ if(!cac_SamSetGroupMembers(hnd, mem_ctx, &set)) {
+ printf("could not set members. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Set users\n");
+ }
+
+ break;
+
+ case 'g': /*list groups for user*/
+ ZERO_STRUCT(ou);
+ ZERO_STRUCT(gg);
+
+ printf("Enter username: ");
+ cactest_readline(stdin, input);
+
+ if(input[0] != '\0') {
+ ou.in.name = talloc_strdup(mem_ctx, input);
+ }
+ else {
+ printf("Enter RID: 0x");
+ scanf("%x", &ou.in.rid);
+ }
+
+ ou.in.access = MAXIMUM_ALLOWED_ACCESS;
+ ou.in.dom_hnd = sod.out.dom_hnd;
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
+ fprintf(stderr, "Could not open user %s. Error: %s\n", ou.in.name, nt_errstr(hnd->status));
+ break;
+ }
+
+ /*now find the groups*/
+ gg.in.user_hnd = ou.out.user_hnd;
+
+ if(!cac_SamGetGroupsForUser(hnd, mem_ctx, &gg)) {
+ fprintf(stderr, "Could not get groups for user. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ cac_SamClose(hnd, mem_ctx, ou.out.user_hnd);
+
+ ZERO_STRUCT(gn);
+
+ gn.in.dom_hnd = sod.out.dom_hnd;
+ gn.in.num_rids = gg.out.num_groups;
+ gn.in.rids = gg.out.rids;
+
+ if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &gn)) {
+ fprintf(stderr, "Could not get names from RIDs. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ printf("%d groups: \n", gn.out.num_names);
+
+ for(i = 0; i < gn.out.num_names; i++) {
+ printf("RID: 0x%x ", gn.out.map[i].rid);
+
+ if(gn.out.map[i].found)
+ printf("Name: %s\n", gn.out.map[i].name);
+ else
+ printf("Unknown RID\n");
+ }
+
+ break;
+
+ case 'z': /*close group*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ if(!cac_SamClose(hnd, mem_ctx, group_hnd)) {
+ printf("Could not close group\n");
+ break;
+ }
+
+ group_hnd = NULL;
+ break;
+
+ case 'i': /*get group info*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gi);
+ gi.in.group_hnd = group_hnd;
+
+ if(!cac_SamGetGroupInfo(hnd, mem_ctx, &gi)) {
+ printf("Could not get group info. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Retrieved Group info\n");
+ print_cac_group_info(gi.out.info);
+ }
+
+ break;
+
+ case 'e': /*edit group info*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gi);
+ ZERO_STRUCT(si);
+
+ gi.in.group_hnd = group_hnd;
+
+ if(!cac_SamGetGroupInfo(hnd, mem_ctx, &gi)) {
+ printf("Could not get group info. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ edit_cac_group_info(mem_ctx, gi.out.info);
+
+ si.in.group_hnd = group_hnd;
+ si.in.info = gi.out.info;
+
+ if(!cac_SamSetGroupInfo(hnd, mem_ctx, &si)) {
+ printf("Could not set group info. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf(" Done.\n");
+ }
+
+ break;
+
+ case 'n': /*rename group*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(rg);
+
+ printf("Enter new group name: ");
+ cactest_readline(stdin, tmp);
+
+ rg.in.group_hnd = group_hnd;
+ rg.in.new_name = talloc_strdup(mem_ctx, tmp);
+
+ if(!cac_SamRenameGroup(hnd, mem_ctx, &rg))
+ printf("Could not rename group. Error: %s\n", nt_errstr(hnd->status));
+ else
+ printf("Done.\n");
+
+ break;
+ case 't': /*get security info*/
+ if(!group_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gso);
+
+ gso.in.pol = group_hnd;
+
+ if(!cac_SamGetSecurityObject(hnd, mem_ctx, &gso)) {
+ printf("Could not get security descriptor info. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Got it.\n");
+ }
+ break;
+
+ case 'q':
+ break;
+
+ default:
+ printf("Invalid command\n");
+ }
+ }
+
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ if(group_hnd)
+ cac_SamClose(hnd, mem_ctx, group_hnd);
+
+done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/sam/samlookup.c b/examples/libmsrpc/test/sam/samlookup.c
new file mode 100644
index 0000000000..32be50d4b9
--- /dev/null
+++ b/examples/libmsrpc/test/sam/samlookup.c
@@ -0,0 +1,140 @@
+/*lookup names or rids*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+
+ struct SamGetNamesFromRids sgn;
+ struct SamGetRidsFromNames sgr;
+
+ fstring tmp;
+ fstring input;
+
+ int i;
+
+ mem_ctx = talloc_init("cac_samenum");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ tmp[0] = 0x00;
+ while(tmp[0] != 'q') {
+ printf("get [n]ames or get [r]ids or [q]uit: ");
+ cactest_readline(stdin, tmp);
+
+ switch(tmp[0]) {
+ case 'n':
+ ZERO_STRUCT(sgn);
+
+ sgn.in.dom_hnd = sod.out.dom_hnd;
+
+ printf("How many rids will you enter: ");
+ scanf("%d", &sgn.in.num_rids);
+
+ sgn.in.rids = talloc_array(mem_ctx, int, sgn.in.num_rids);
+
+ for(i = 0; i < sgn.in.num_rids; i++) {
+ printf(" Enter RID %d: 0x", i);
+ scanf("%x", &sgn.in.rids[i]);
+ }
+
+ printf("Getting names...\n");
+
+ if(!cac_SamGetNamesFromRids(hnd, mem_ctx, &sgn)) {
+ fprintf(stderr, "could not lookup names. Error: %s\n", nt_errstr(hnd->status));
+ talloc_free(sgn.in.rids);
+ continue;
+ }
+
+ printf("Found %d names:\n", sgn.out.num_names);
+
+ for(i = 0; i < sgn.out.num_names; i++) {
+ printf(" RID: 0x%x ", sgn.out.map[i].rid);
+
+ if(sgn.out.map[i].found) {
+ printf("Name: %s\n", sgn.out.map[i].name);
+ }
+ else {
+ printf("Unknown RID\n");
+ }
+
+ }
+
+ break;
+
+ case 'r':
+ ZERO_STRUCT(sgr);
+
+ sgr.in.dom_hnd = sod.out.dom_hnd;
+
+ printf("How many names will you enter: ");
+ scanf("%d", &sgr.in.num_names);
+
+ sgr.in.names = talloc_array(mem_ctx, char *, sgr.in.num_names);
+
+ for(i = 0; i < sgr.in.num_names; i++) {
+ printf(" Enter name %d: ", (i+1));
+ cactest_readline(stdin, input);
+
+ sgr.in.names[i] = talloc_strdup(mem_ctx, input);
+ }
+
+ if(!cac_SamGetRidsFromNames(hnd, mem_ctx, &sgr)) {
+ fprintf(stderr, "Could not lookup names. Error: %s\n", nt_errstr(hnd->status));
+ continue;
+ }
+
+ printf("Found %d RIDs:\n", sgr.out.num_rids);
+
+ for(i = 0; i < sgr.out.num_rids; i++) {
+ printf(" Name: %s ", sgr.out.map[i].name);
+
+ if(sgr.out.map[i].found) {
+ printf("RID: 0x%x\n", sgr.out.map[i].rid);
+ }
+ else {
+ printf("Unknown name\n");
+ }
+ }
+
+ break;
+ case 'q':
+ printf("\n");
+ break;
+ default:
+ printf("Invalid command!\n");
+ }
+ }
+
+
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+ cac_SamClose(hnd, mem_ctx, sod.out.sam);
+
+done:
+ talloc_destroy(mem_ctx);
+ cac_FreeHandle(hnd);
+
+ return 0;
+
+}
+
diff --git a/examples/libmsrpc/test/sam/samuser.c b/examples/libmsrpc/test/sam/samuser.c
new file mode 100644
index 0000000000..df56a2d991
--- /dev/null
+++ b/examples/libmsrpc/test/sam/samuser.c
@@ -0,0 +1,294 @@
+/*Some user management stuff*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+
+ struct SamOpenUser ou;
+ struct SamEnumUsers eu;
+ struct SamCreateUser cu;
+ struct SamGetUserInfo gi;
+ struct SamSetUserInfo si;
+ struct SamRenameUser ru;
+ struct SamSetPassword sp;
+
+ POLICY_HND *user_hnd = NULL;
+
+ fstring tmp;
+ fstring input;
+
+ char *pass1 = NULL;
+ char *pass2 = NULL;
+
+ int i;
+
+ mem_ctx = talloc_init("cac_samgroup");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ struct SamOpenDomain sod;
+ ZERO_STRUCT(sod);
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod)) {
+ fprintf(stderr, "Could not open domain. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ tmp[0] = 0x00;
+ while(tmp[0] != 'q') {
+ printf("\n");
+ printf("[l]ist users\n");
+ printf("[c]reate user\n");
+ printf("[o]pen user\n");
+ printf("[d]elete user\n");
+ printf("[g]et user info\n");
+ printf("[e]dit user info\n");
+ printf("[r]ename user\n");
+ printf("reset [p]assword\n");
+ printf("[n] close user\n");
+
+ printf("[q]uit\n\n");
+ printf("Enter option: ");
+ cactest_readline(stdin, tmp);
+
+ printf("\n");
+
+ switch(tmp[0]) {
+ case 'c': /*create user*/
+ if(user_hnd != NULL) {
+ /*then we have an open handle.. close it*/
+ cac_SamClose(hnd, mem_ctx, user_hnd);
+ user_hnd = NULL;
+ }
+
+ printf("Enter user name: ");
+ cactest_readline(stdin, input);
+
+ ZERO_STRUCT(cu);
+
+ cu.in.name = talloc_strdup(mem_ctx, input);
+ cu.in.dom_hnd = sod.out.dom_hnd;
+ cu.in.acb_mask = ACB_NORMAL;
+
+ if(!cac_SamCreateUser(hnd, mem_ctx, &cu)) {
+ printf("Could not create user. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Created user %s with RID 0x%x\n", cu.in.name, cu.out.rid);
+ user_hnd = cu.out.user_hnd;
+ }
+
+ break;
+
+ case 'o': /*open group*/
+ if(user_hnd != NULL) {
+ /*then we have an open handle.. close it*/
+ cac_SamClose(hnd, mem_ctx, user_hnd);
+ user_hnd = NULL;
+ }
+
+ ZERO_STRUCT(ou);
+
+ ou.in.dom_hnd = sod.out.dom_hnd;
+ ou.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ printf("Enter RID: 0x");
+ scanf("%x", &ou.in.rid);
+
+ if(!cac_SamOpenUser(hnd, mem_ctx, &ou)) {
+ fprintf(stderr, "Could not open user. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Opened user\n");
+ user_hnd = ou.out.user_hnd;
+ }
+
+ break;
+
+ case 'l': /*list users*/
+ ZERO_STRUCT(eu);
+ eu.in.dom_hnd = sod.out.dom_hnd;
+
+ while(cac_SamEnumUsers(hnd, mem_ctx, &eu)) {
+ for(i = 0; i < eu.out.num_users; i++) {
+ printf("RID: 0x%x Name: %s\n", eu.out.rids[i], eu.out.names[i]);
+ }
+ }
+
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Could not enumerate Users. Error: %s\n", nt_errstr(hnd->status));
+ }
+
+ break;
+
+ break;
+
+ case 'd': /*delete group*/
+ if(!user_hnd) {
+ printf("Must open group first!\n");
+ break;
+ }
+
+ if(!cac_SamDeleteGroup(hnd, mem_ctx, user_hnd)) {
+ fprintf(stderr, "Could not delete group. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Deleted group.\n");
+ user_hnd = NULL;
+ }
+ break;
+
+
+ case 'n':
+ if(!user_hnd) {
+ printf("Must open user first!\n");
+ break;
+ }
+
+ if(!cac_SamClose(hnd, mem_ctx, user_hnd)) {
+ printf("Could not user group\n");
+ break;
+ }
+
+ user_hnd = NULL;
+ break;
+
+ case 'g': /*get user info*/
+ if(!user_hnd) {
+ printf("Must open user first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gi);
+ gi.in.user_hnd = ou.out.user_hnd;
+
+ if(!cac_SamGetUserInfo(hnd, mem_ctx, &gi)) {
+ printf("Could not get user info. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Retrieved User information:\n");
+ print_cac_user_info(gi.out.info);
+ }
+
+ break;
+
+ case 'e': /*edit user info*/
+ if(!user_hnd) {
+ printf("Must Open user first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gi);
+ gi.in.user_hnd = ou.out.user_hnd;
+ if(!cac_SamGetUserInfo(hnd, mem_ctx, &gi)) {
+ printf("Could not get user info. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ edit_cac_user_info(mem_ctx, gi.out.info);
+
+ printf("setting following info:\n");
+ print_cac_user_info(gi.out.info);
+
+ ZERO_STRUCT(si);
+
+ si.in.user_hnd = user_hnd;
+ si.in.info = gi.out.info;
+
+ if(!cac_SamSetUserInfo(hnd, mem_ctx, &si)) {
+ printf("Could not set user info. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Done.\n");
+ }
+
+ break;
+
+ case 'r': /*rename user*/
+ if(!user_hnd) {
+ printf("Must open user first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(ru);
+
+ printf("Enter new username: ");
+ cactest_readline(stdin, tmp);
+
+ ru.in.user_hnd = user_hnd;
+ ru.in.new_name = talloc_strdup(mem_ctx, tmp);
+
+ if(!cac_SamRenameUser(hnd, mem_ctx, &ru)) {
+ printf("Could not rename user. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Renamed user\n");
+ }
+
+ break;
+
+ case 'p': /*reset password*/
+
+ if(!user_hnd) {
+ printf("Must open user first!\n");
+ break;
+ }
+
+ do {
+ if(pass1 && pass2) {
+ printf("Passwords do not match. Please try again\n");
+ }
+
+ pass1 = getpass("Enter new password: ");
+ pass2 = getpass("Re-enter new password: ");
+ } while(strncmp(pass1, pass2, MAX_PASS_LEN));
+
+ ZERO_STRUCT(sp);
+ sp.in.user_hnd = user_hnd;
+ sp.in.password = talloc_strdup(mem_ctx, pass1);
+
+ if(!cac_SamSetPassword(hnd, mem_ctx, &sp)) {
+ printf("Could not set password. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Done.\n");
+ }
+
+ break;
+
+ case 'q':
+ break;
+
+ default:
+ printf("Invalid command\n");
+ }
+ }
+
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ if(user_hnd)
+ cac_SamClose(hnd, mem_ctx, user_hnd);
+
+done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/smbc_test/smbc.c b/examples/libmsrpc/test/smbc_test/smbc.c
new file mode 100644
index 0000000000..3db3ceadc6
--- /dev/null
+++ b/examples/libmsrpc/test/smbc_test/smbc.c
@@ -0,0 +1,87 @@
+/*simple test for libsmbclient compatibility. initialize a smbc context, open sessions on a couple pipes and quit*/
+
+#include "libmsrpc.h"
+#include "libsmbclient.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ SMBCCTX *ctx = NULL;
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ struct LsaOpenPolicy lop;
+ struct RegConnect rc;
+ struct SamOpenDomain sod;
+
+ ZERO_STRUCT(lop);
+ ZERO_STRUCT(rc);
+ ZERO_STRUCT(sod);
+
+ mem_ctx = talloc_init("cac_smbc");
+ if(!mem_ctx) {
+ printf("Could not initialize talloc context\n");
+ exit(-1);
+ }
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ /*initialize smbc context*/
+ if( (ctx = smbc_new_context()) == NULL) {
+ exit(1);
+ }
+
+ /*this probably isn't what someone would want to do, but it initializes the values we need*/
+ ctx->debug = hnd->debug;
+ ctx->callbacks.auth_fn = cac_GetAuthDataFn;
+
+
+ if(smbc_init_context(ctx) == NULL)
+ exit(1);
+
+ cac_SetSmbcContext(hnd, ctx);
+
+ /*still have to call cac_Connect()*/
+ if(!cac_Connect(hnd, NULL)) {
+ printf("Could not connect to server\n");
+ exit(1);
+ }
+
+ lop.in.access = MAXIMUM_ALLOWED_ACCESS;
+ if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop))
+ printf("Could not open LSA policy. Error: %s\n", nt_errstr(hnd->status));
+
+ printf("Opened LSA policy.\n");
+
+ rc.in.access = MAXIMUM_ALLOWED_ACCESS;
+ rc.in.root = HKEY_LOCAL_MACHINE;
+ if(!cac_RegConnect(hnd, mem_ctx, &rc))
+ printf("Could not connect to registry. Error: %s\n", nt_errstr(hnd->status));
+
+ printf("Connceted to Registry.\n");
+
+ sod.in.access = MAXIMUM_ALLOWED_ACCESS;
+
+ if(!cac_SamOpenDomain(hnd, mem_ctx, &sod))
+ printf("Could not open domain SAM. Error: %s\n", nt_errstr(hnd->status));
+
+ printf("Opened domain.\n");
+
+ if(lop.out.pol)
+ cac_LsaClosePolicy(hnd, mem_ctx, lop.out.pol);
+
+ if(rc.out.key)
+ cac_RegClose(hnd, mem_ctx, rc.out.key);
+
+ if(sod.out.sam)
+ cac_SamClose(hnd, mem_ctx, sod.out.sam);
+
+ if(sod.out.dom_hnd)
+ cac_SamClose(hnd, mem_ctx, sod.out.dom_hnd);
+
+ cac_FreeHandle(hnd);
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/examples/libmsrpc/test/svcctl/svc.c b/examples/libmsrpc/test/svcctl/svc.c
new file mode 100644
index 0000000000..db5fa27895
--- /dev/null
+++ b/examples/libmsrpc/test/svcctl/svc.c
@@ -0,0 +1,303 @@
+/*Tests all of the svcctl calls (at least at time of writing)*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+int main(int argc, char **argv) {
+ CacServerHandle *hnd = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+
+
+ struct SvcOpenScm sos;
+ struct SvcEnumServices es;
+ struct SvcOpenService os;
+ struct SvcGetStatus gs;
+ struct SvcStartService start;
+ struct SvcStopService stop;
+ struct SvcPauseService pause;
+ struct SvcContinueService res;
+ struct SvcGetDisplayName gdn;
+ struct SvcGetServiceConfig sgc;
+
+ POLICY_HND *svc_hnd = NULL;
+
+ fstring tmp;
+ fstring input;
+
+ int i;
+
+ mem_ctx = talloc_init("cac_samgroup");
+
+ hnd = cac_NewServerHandle(True);
+
+ cac_SetAuthDataFn(hnd, cactest_GetAuthDataFn);
+
+ cac_parse_cmd_line(argc, argv, hnd);
+
+ if(!cac_Connect(hnd, NULL)) {
+ fprintf(stderr, "Could not connect to server %s. Error: %s\n", hnd->server, nt_errstr(hnd->status));
+ exit(-1);
+ }
+
+ /*open a handle to the scm*/
+ ZERO_STRUCT(sos);
+
+ sos.in.access = SC_MANAGER_ALL_ACCESS;
+
+ if(!cac_SvcOpenScm(hnd, mem_ctx, &sos)) {
+ fprintf(stderr, "Could not open SCM. Error: %s\n", nt_errstr(hnd->status));
+ goto done;
+ }
+
+ printf("Opened SCM\n");
+
+ tmp[0] = 0x00;
+ while(tmp[0] != 'q') {
+ printf("\n");
+ printf("[e] Enum Services\n");
+ printf("[o] Open Service\n");
+ printf("[x] Close Service\n");
+ printf("[g] Get service status\n");
+ printf("[s] Start service\n");
+ printf("[t] Stop service\n");
+ printf("[p] Pause service\n");
+ printf("[r] Resume service\n");
+ printf("[c] Get service config\n");
+
+ printf("[d] Get display name\n");
+
+ printf("[q]uit\n\n");
+ printf("Enter option: ");
+ cactest_readline(stdin, tmp);
+
+ printf("\n");
+
+ switch(tmp[0]) {
+ case 'e': /*enum services*/
+ ZERO_STRUCT(es);
+ es.in.scm_hnd = sos.out.scm_hnd;
+
+ if(!cac_SvcEnumServices(hnd, mem_ctx, &es)) {
+ printf("Could not enumerate services. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ for(i = 0; i < es.out.num_services; i++) {
+ print_cac_service(es.out.services[i]);
+ }
+ printf("Enumerated %d services:\n", es.out.num_services);
+
+ break;
+
+ case 'o': /*Open service*/
+ ZERO_STRUCT(os);
+
+ printf("Enter service name: ");
+ cactest_readline(stdin, tmp);
+
+ os.in.name = talloc_strdup(mem_ctx, tmp);
+ os.in.scm_hnd = sos.out.scm_hnd;
+ os.in.access = SERVICE_ALL_ACCESS;
+
+ if(!cac_SvcOpenService(hnd, mem_ctx, &os)) {
+ printf("Could not open service. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ printf("Opened service.\n");
+ svc_hnd = os.out.svc_hnd;
+
+ break;
+ case 'x': /*close service*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ cac_SvcClose(hnd, mem_ctx, svc_hnd);
+ svc_hnd = NULL;
+ break;
+ case 'g': /*get svc status*/
+
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gs);
+
+ gs.in.svc_hnd = svc_hnd;
+
+ if(!cac_SvcGetStatus(hnd, mem_ctx, &gs)) {
+ printf("Could not get status. Error: %s\n", nt_errstr(hnd->status));
+ break;
+ }
+
+ print_service_status(gs.out.status);
+ break;
+ case 's': /*start service*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(start);
+
+ start.in.svc_hnd = svc_hnd;
+
+ printf("Enter number of parameters: ");
+ scanf("%d", &start.in.num_parms);
+
+ start.in.parms = talloc_array(mem_ctx, char *, start.in.num_parms);
+
+ for(i = 0; i < start.in.num_parms; i++) {
+ printf("Parm %d: ", i);
+ cactest_readline(stdin, tmp);
+ start.in.parms[i] = talloc_strdup(mem_ctx, tmp);
+ }
+
+ printf("Timeout (seconds): ");
+ scanf("%d", &start.in.timeout);
+
+ if(!cac_SvcStartService(hnd, mem_ctx, &start)) {
+ printf("Could not start service. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Started service.\n");
+ }
+
+ break;
+ case 't': /*stop service*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(stop);
+ stop.in.svc_hnd = svc_hnd;
+
+ printf("Timeout (seconds): ");
+ scanf("%d", &stop.in.timeout);
+
+ if(!cac_SvcStopService(hnd, mem_ctx, &stop)) {
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Error occured: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Service was not stopped within %d seconds.\n", stop.in.timeout);
+ print_service_status(stop.out.status);
+ }
+ }
+ else {
+ printf("Done.\n");
+ print_service_status(stop.out.status);
+ }
+ break;
+ case 'd': /*get display name*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(gdn);
+ gdn.in.svc_hnd = svc_hnd;
+
+ if(!cac_SvcGetDisplayName(hnd, mem_ctx, &gdn)) {
+ printf("Could not get display name. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("\tDisplay Name: %s\n", gdn.out.display_name);
+ }
+ break;
+
+ case 'p': /*pause service*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(pause);
+ pause.in.svc_hnd = svc_hnd;
+
+ printf("Timeout (seconds): ");
+ scanf("%d", &pause.in.timeout);
+
+ if(!cac_SvcPauseService(hnd, mem_ctx, &pause)) {
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Error occured: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Service was not paused within %d seconds.\n", pause.in.timeout);
+ print_service_status(pause.out.status);
+ }
+ }
+ else {
+ printf("Done.\n");
+ print_service_status(pause.out.status);
+ }
+
+ break;
+
+ case 'r': /*resume service*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(res);
+ res.in.svc_hnd = svc_hnd;
+
+ printf("Timeout (seconds): ");
+ scanf("%d", &res.in.timeout);
+
+ if(!cac_SvcContinueService(hnd, mem_ctx, &res)) {
+ if(CAC_OP_FAILED(hnd->status)) {
+ printf("Error occured: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ printf("Service was not resumed within %d seconds.\n", res.in.timeout);
+ print_service_status(res.out.status);
+ }
+ }
+ else {
+ printf("Done.\n");
+ print_service_status(res.out.status);
+ }
+
+ break;
+
+ case 'c': /*get service config*/
+ if(!svc_hnd) {
+ printf("Must open service first!\n");
+ break;
+ }
+
+ ZERO_STRUCT(sgc);
+
+ sgc.in.svc_hnd = svc_hnd;
+
+ if(!cac_SvcGetServiceConfig(hnd, mem_ctx, &sgc)) {
+ printf("Could not get service config. Error: %s\n", nt_errstr(hnd->status));
+ }
+ else {
+ print_service_config(&sgc.out.config);
+ }
+ break;
+
+ case 'q': /*quit*/
+ break;
+ default:
+ printf("Invalid command\n");
+ }
+ }
+
+ cac_SvcClose(hnd, mem_ctx, sos.out.scm_hnd);
+
+ done:
+ cac_FreeHandle(hnd);
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
+
diff --git a/examples/libmsrpc/test/test_util.c b/examples/libmsrpc/test/test_util.c
new file mode 100644
index 0000000000..81a9c9203d
--- /dev/null
+++ b/examples/libmsrpc/test/test_util.c
@@ -0,0 +1,408 @@
+/*some utility functions for the registry tests*/
+
+#include "libmsrpc.h"
+#include "test_util.h"
+
+
+void cactest_print_usage(char **argv) {
+ printf("Usage:\n");
+ printf(" %s server [-U username] [-W domain] [-P passwprd] [-N netbios_name]\n", argv[0]);
+}
+
+/*allocates memory for auth info and parses domain/user/server out of command line*/
+void cac_parse_cmd_line(int argc, char **argv, CacServerHandle *hnd) {
+ int i = 0;
+
+ ZERO_STRUCTP(hnd->username);
+ ZERO_STRUCTP(hnd->domain);
+ ZERO_STRUCTP(hnd->netbios_name);
+ ZERO_STRUCTP(hnd->password);
+
+ for(i = 1; i < argc; i++) {
+ if( strncmp(argv[i], "-U", sizeof(fstring)) == 0) {
+ strncpy(hnd->username, argv[i+1], sizeof(fstring));
+ i++;
+ }
+
+ else if(strncmp(argv[i], "-W", sizeof(fstring)) == 0) {
+ strncpy(hnd->domain, argv[i+1], sizeof(fstring));
+ i++;
+
+ }
+
+ else if(strncmp(argv[i], "-P", sizeof(fstring)) == 0) {
+ strncpy(hnd->password, argv[i+1], sizeof(fstring));
+ i++;
+
+ }
+
+ else if(strncmp(argv[i], "-N", sizeof(fstring)) == 0) {
+ strncpy(hnd->netbios_name, argv[i+1], sizeof(fstring));
+ i++;
+ }
+
+ else if(strncmp(argv[i], "-d", sizeof(fstring)) == 0) {
+ sscanf(argv[i+1], "%d", &hnd->debug);
+ i++;
+ }
+
+ else { /*assume this is the server name*/
+ strncpy(hnd->server, argv[i], sizeof(fstring));
+ }
+ }
+
+ if(!hnd->server) {
+ cactest_print_usage(argv);
+ cac_FreeHandle(hnd);
+ exit(-1);
+ }
+
+}
+
+void print_value(uint32 type, REG_VALUE_DATA *data) {
+ int i = 0;
+
+ switch(type) {
+ case REG_SZ:
+ printf(" Type: REG_SZ\n");
+ printf(" Value: %s\n", data->reg_sz);
+ break;
+ case REG_EXPAND_SZ:
+ printf(" Type: REG_EXPAND_SZ\n");
+ printf(" Value: %s\n", data->reg_expand_sz);
+ break;
+ case REG_MULTI_SZ:
+ printf(" Type: REG_MULTI_SZ\n");
+ printf(" Values: ");
+
+ for(i = 0; i < data->reg_multi_sz.num_strings; i++) {
+ printf(" %d: %s\n", i, data->reg_multi_sz.strings[i]);
+ }
+ break;
+ case REG_DWORD:
+ printf(" Type: REG_DWORD\n");
+ printf(" Value: %d\n", data->reg_dword);
+ break;
+ case REG_DWORD_BE:
+ printf(" Type: REG_DWORD_BE\n");
+ printf(" Value: 0x%x\n", data->reg_dword_be);
+ break;
+ case REG_BINARY:
+ printf(" Type: REG_BINARY\n");
+ break;
+ default:
+ printf(" Invalid type: %d\n", type);
+
+ }
+
+ printf("\n");
+
+}
+
+void cactest_readline(FILE *in, fstring line) {
+
+ int c;
+
+ c = fgetc(in);
+ if(c != '\n')
+ ungetc(c, in);
+
+ fgets(line, sizeof(fstring), in);
+
+ if(line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+
+}
+
+void cactest_GetAuthDataFn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword)
+
+{
+ char temp[sizeof(fstring)];
+
+ static char authUsername[sizeof(fstring)];
+ static char authWorkgroup[sizeof(fstring)];
+ static char authPassword[sizeof(fstring)];
+ static char authSet = 0;
+
+ char *pass = NULL;
+
+ if (authSet)
+ {
+ strncpy(pWorkgroup, authWorkgroup, maxLenWorkgroup - 1);
+ strncpy(pUsername, authUsername, maxLenUsername - 1);
+ strncpy(pPassword, authPassword, maxLenPassword - 1);
+ }
+ else
+ {
+ if(pWorkgroup[0] != '\0') {
+ strncpy(authWorkgroup, pWorkgroup, maxLenWorkgroup - 1);
+ }
+ else {
+ d_printf("Domain: [%s] ", pWorkgroup);
+ fscanf(stdin, "%s", temp);
+
+ if (temp[0] != '\0')
+ {
+ strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
+ strncpy(authWorkgroup, temp, maxLenWorkgroup - 1);
+ }
+ }
+
+
+ if(pUsername[0] != '\0') {
+ strncpy(authUsername, pUsername, maxLenUsername - 1);
+ }
+ else {
+ d_printf("Username: [%s] ", pUsername);
+ fscanf(stdin, "%s", temp);
+
+ if (temp[strlen(temp) - 1] == '\n') /* A new line? */
+ {
+ temp[strlen(temp) - 1] = '\0';
+ }
+
+ if (temp[0] != '\0')
+ {
+ strncpy(pUsername, temp, maxLenUsername - 1);
+ strncpy(authUsername, pUsername, maxLenUsername - 1);
+ }
+ }
+ if(pPassword[0] != '\0') {
+ strncpy(authPassword, pPassword, maxLenPassword - 1);
+ }
+ else {
+ pass = getpass("Password: ");
+ if (pass)
+ fstrcpy(temp, pass);
+ if (temp[strlen(temp) - 1] == '\n') /* A new line? */
+ {
+ temp[strlen(temp) - 1] = '\0';
+ }
+ if (temp[0] != '\0')
+ {
+ strncpy(pPassword, temp, maxLenPassword - 1);
+ strncpy(authPassword, pPassword, maxLenPassword - 1);
+ }
+ }
+ authSet = 1;
+ }
+}
+
+void cactest_reg_input_val(TALLOC_CTX *mem_ctx, int *type, char **name, REG_VALUE_DATA *data) {
+ fstring tmp;
+ int i;
+
+ printf("Enter value name: \n");
+ cactest_readline(stdin, tmp);
+ *name = talloc_strdup(mem_ctx, tmp);
+
+ do {
+ printf("Enter type. %d = REG_SZ, %d = REG_DWORD, %d = REG_MULTI_SZ: ", REG_SZ, REG_DWORD, REG_MULTI_SZ);
+ scanf("%d", type);
+ } while(*type != REG_SZ && *type != REG_DWORD && *type != REG_MULTI_SZ);
+
+ switch(*type) {
+ case REG_SZ:
+ printf("Enter string:\n");
+ cactest_readline(stdin, tmp);
+
+ data->reg_sz = talloc_strdup(mem_ctx, tmp);
+ break;
+
+ case REG_DWORD:
+ printf("Enter dword: ");
+ scanf("%d", &data->reg_dword);
+ break;
+
+ case REG_MULTI_SZ:
+ printf("Enter number of strings: ");
+ scanf("%d", &data->reg_multi_sz.num_strings);
+
+ data->reg_multi_sz.strings = talloc_array(mem_ctx, char *, data->reg_multi_sz.num_strings);
+
+ for(i = 0; i < data->reg_multi_sz.num_strings; i++) {
+ printf("String %d: ", i+1);
+ cactest_readline(stdin, tmp);
+
+ data->reg_multi_sz.strings[i] = talloc_strdup(mem_ctx, tmp);
+ }
+ break;
+ }
+}
+
+void print_cac_user_info(CacUserInfo *info) {
+ printf(" User Name : %s\n", info->username);
+ printf(" Full Name : %s\n", info->full_name);
+ printf(" Home Dir : %s\n", info->home_dir);
+ printf(" Home Drive : %s\n", info->home_drive);
+ printf(" Profile Path : %s\n", info->profile_path);
+ printf(" Logon Script : %s\n", info->logon_script);
+ printf(" Description : %s\n", info->description);
+ printf(" Workstations : %s\n", info->workstations);
+ printf(" Remote Dial : %s\n", info->dial);
+
+ printf(" Logon Time : %s\n", http_timestring(info->logon_time));
+ printf(" Logoff Time : %s\n", http_timestring(info->logoff_time));
+ printf(" Kickoff Time : %s\n", http_timestring(info->kickoff_time));
+ printf(" Pass last set: %s\n", http_timestring(info->pass_last_set_time));
+ printf(" Pass can set : %s\n", http_timestring(info->pass_can_change_time));
+ printf(" Pass must set: %s\n", http_timestring(info->pass_must_change_time));
+
+ printf(" User RID : 0x%x\n", info->rid);
+ printf(" Group RID : 0x%x\n", info->group_rid);
+ printf(" ACB Mask : 0x%x\n", info->acb_mask);
+
+ printf(" Bad pwd count: %d\n", info->bad_passwd_count);
+ printf(" Logon Cuont : %d\n", info->logon_count);
+
+ printf(" NT Password : %s\n", info->nt_password);
+ printf(" LM Password : %s\n", info->lm_password);
+
+}
+
+void edit_readline(fstring line) {
+ fgets(line, sizeof(fstring), stdin);
+
+ if(line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = '\0';
+}
+void edit_cac_user_info(TALLOC_CTX *mem_ctx, CacUserInfo *info) {
+ fstring tmp;
+
+ printf(" User Name [%s]: ", info->username);
+ edit_readline(tmp);
+
+ if(tmp[0] != '\0')
+ info->username = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Full Name [%s]: ", info->full_name);
+
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ info->full_name = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Description [%s]: ", info->description);
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ info->description = talloc_strdup(mem_ctx, tmp);
+
+ printf(" Remote Dial [%s]: ", info->dial);
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ info->dial = talloc_strdup(mem_ctx, tmp);
+
+ printf(" ACB Mask [0x%x]: ", info->acb_mask);
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ sscanf(tmp, "%x", &info->acb_mask);
+
+ printf(" Must change pass at next logon? [y/N]: ");
+ edit_readline(tmp);
+
+ if(tmp[0] == 'y' || tmp[0] == 'Y')
+ info->pass_must_change= True;
+
+}
+
+void print_cac_group_info(CacGroupInfo *info) {
+ printf(" Group Name : %s\n", info->name);
+ printf(" Description : %s\n", info->description);
+ printf(" Num Members : %d\n", info->num_members);
+}
+
+void edit_cac_group_info(TALLOC_CTX *mem_ctx, CacGroupInfo *info) {
+ fstring tmp;
+
+ printf("Group Name [%s]: ", info->name);
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ info->name = talloc_strdup(mem_ctx, tmp);
+
+ printf("Description [%s]: ", info->description);
+ edit_readline(tmp);
+ if(tmp[0] != '\0')
+ info->description = talloc_strdup(mem_ctx, tmp);
+}
+
+char *srv_role_str(uint32 role) {
+ switch(role) {
+ case ROLE_STANDALONE:
+ return "STANDALONE";
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ return "DOMAIN_MEMBER";
+ break;
+ case ROLE_DOMAIN_BDC:
+ return "DOMAIN_BDC";
+ break;
+ case ROLE_DOMAIN_PDC:
+ return "DOMAIN_PDC";
+ break;
+ }
+
+ return "Invalid role!\n";
+}
+
+char *cactime_str(CacTime ctime, fstring tmp) {
+
+ snprintf(tmp, sizeof(fstring), "%u Days, %u Hours, %u Minutes, %u Seconds", ctime.days, ctime.hours, ctime.minutes, ctime.seconds);
+
+ return tmp;
+}
+
+void print_cac_domain_info(CacDomainInfo *info) {
+ fstring tmp;
+
+ printf(" Server Role : %s\n", srv_role_str(info->server_role));
+ printf(" Num Users : %d\n", info->num_users);
+ printf(" Num Domain Groups: %d\n", info->num_domain_groups);
+ printf(" Num Local Groups : %d\n", info->num_local_groups);
+ printf(" Comment : %s\n", info->comment);
+ printf(" Domain Name : %s\n", info->domain_name);
+ printf(" Server Name : %s\n", info->server_name);
+ printf(" Min. Pass. Length: %d\n", info->min_pass_length);
+ printf(" Password History : %d\n", info->pass_history);
+ printf("\n");
+ printf(" Passwords Expire In : %s\n", cactime_str(info->expire, tmp));
+ printf(" Passwords Can Change in: %s\n", cactime_str(info->min_pass_age, tmp));
+ printf(" Lockouts last : %s\n", cactime_str(info->lockout_duration, tmp));
+ printf(" Allowed Bad Attempts : %d\n", info->num_bad_attempts);
+}
+
+void print_cac_service(CacService svc) {
+ printf("\tService Name: %s\n", svc.service_name);
+ printf("\tDisplay Name: %s\n", svc.display_name);
+ print_service_status(svc.status);
+}
+
+void print_service_status(SERVICE_STATUS status) {
+ printf("\tStatus:\n");
+ printf("\t Type: 0x%x\n", status.type);
+ printf("\t State: 0x%x\n", status.state);
+ printf("\t Controls: 0x%x\n", status.controls_accepted);
+ printf("\t W32 Exit Code: 0x%x\n", status.win32_exit_code);
+ printf("\t SVC Exit Code: 0x%x\n", status.service_exit_code);
+ printf("\t Checkpoint: 0x%x\n", status.check_point);
+ printf("\t Wait Hint: 0x%x\n", status.wait_hint);
+ printf("\n");
+}
+
+void print_service_config(CacServiceConfig *config) {
+ printf("\tConfig:\n");
+ printf("\tType: 0x%x\n", config->type);
+ printf("\tStart Type: 0x%x\n", config->start_type);
+ printf("\tError config: 0x%x\n", config->error_control);
+ printf("\tExecutable Path: %s\n", config->exe_path);
+ printf("\tLoad Order Group: %s\n", config->load_order_group);
+ printf("\tTag ID: 0x%x\n", config->tag_id);
+ printf("\tDependencies: %s\n", config->dependencies);
+ printf("\tStart Name: %s\n", config->start_name);
+ printf("\tDisplay Name: %s\n", config->display_name);
+}
diff --git a/examples/libmsrpc/test/test_util.h b/examples/libmsrpc/test/test_util.h
new file mode 100644
index 0000000000..9b27599da1
--- /dev/null
+++ b/examples/libmsrpc/test/test_util.h
@@ -0,0 +1,31 @@
+#ifndef TEST_UTIL_H
+#define TEST_UTIL_H
+
+#include "libmsrpc.h"
+
+/*prototypes*/
+void cactest_GetAuthDataFn(const char * pServer,
+ const char * pShare,
+ char * pWorkgroup,
+ int maxLenWorkgroup,
+ char * pUsername,
+ int maxLenUsername,
+ char * pPassword,
+ int maxLenPassword);
+
+
+void cactest_print_usage(char **argv);
+void cac_parse_cmd_line(int argc, char **argv, CacServerHandle *hnd);
+void print_value(uint32 type, REG_VALUE_DATA *data);
+void cactest_readline(FILE *in, fstring line);
+void cactest_reg_input_val(TALLOC_CTX *mem_ctx, int *type, char **name, REG_VALUE_DATA *data);
+void print_cac_user_info(CacUserInfo *info);
+void edit_cac_user_info(TALLOC_CTX *mem_ctx, CacUserInfo *info);
+void print_cac_group_info(CacGroupInfo *info);
+void edit_cac_group_info(TALLOC_CTX *mem_ctx, CacGroupInfo *info);
+void print_cac_domain_info(CacDomainInfo *info);
+void print_cac_service(CacService svc);
+void print_service_status(SERVICE_STATUS status);
+void print_service_config(CacServiceConfig *config);
+
+#endif /*TEST_UTIL_H*/