1/* 2 * SAMR test 3 * 4 * Jim Doyle, jrd@bu.edu, 09-05-1998 5 * Stefan Metzmacher, metze@samba.org, 2008 6 * 7 */ 8#if HAVE_CONFIG_H 9#include <config.h> 10#endif 11 12#define getopt getopt_system 13 14#include <stdio.h> 15#include <string.h> 16#include <stdlib.h> 17#include <compat/dcerpc.h> 18#include "samrt.h" 19#include <misc.h> 20 21#undef getopt 22 23#ifdef HAVE_GETOPT_H 24#include <getopt.h> 25#endif 26 27#define MAX_USER_INPUT 128 28#define MAX_LINE 128 29 30/* 31 * Forward declarations 32 */ 33 34static int 35get_client_rpc_binding(rpc_binding_handle_t *, const char *, 36 rpc_if_handle_t, const char *, const char *, const char *); 37 38/* 39 * usage() 40 */ 41 42static void usage(void) 43{ 44 printf("usage: samrt [-h hostname] [-u] [-t] [-k]\n"); 45 printf(" -u: use UDP protocol \n"); 46 printf(" -t: use TCP protocol (default) \n"); 47 printf(" -v: more verbosity\n"); 48 printf(" -k: use gss_mskrb\n"); 49 printf(" -h: specify host where RPC server lives \n"); 50 exit(0); 51} 52 53int main(int argc, char *argv[]) 54{ 55 56 /* 57 * command line processing and options stuff 58 */ 59 60 extern char *optarg; 61 extern int optind, opterr, optopt; 62 int c; 63 64 int verbose = 1; 65 int use_udp = 0; 66 int use_tcp = 0; 67 char mech[128] = "spnego"; 68 char level[128] = "connect"; 69 char rpc_host[128] = "localhost"; 70 const char * protocol; 71 72 /* 73 * stuff needed to make RPC calls 74 */ 75 76 unsigned32 status; 77 rpc_binding_handle_t samr_server; 78 long ntstatus = 0; 79 void *handle = NULL; 80 unsigned32 authn_protocol; 81 void *mech_ctx; 82 83 /* 84 * Process the cmd line args 85 */ 86 87 while ((c = getopt(argc, argv, "h:l:m:utvv:")) != EOF) 88 { 89 switch (c) 90 { 91 case 'u': 92 use_udp = 1; 93 break; 94 case 't': 95 use_tcp = 1; 96 break; 97 case 'v': 98 verbose = 0; 99 break; 100 case 'm': 101 strncpy(mech, optarg, sizeof(level)-1); 102 break; 103 case 'l': 104 strncpy(level, optarg, sizeof(level)-1); 105 break; 106 case 'h': 107 strncpy(rpc_host, optarg, sizeof(rpc_host)-1); 108 break; 109 default: 110 usage(); 111 } 112 } 113 114 if (!use_tcp && !use_udp) use_tcp=1; 115 116 if (use_udp) 117 protocol = "udp"; 118 else 119 protocol = "tcp"; 120 121 /* 122 * Get a binding handle to the server using the following params: 123 * 124 * 1. the hostname where the server lives 125 * 2. the interface description structure of the IDL interface 126 * 3. the desired transport protocol (UDP or TCP) 127 */ 128 129 if (get_client_rpc_binding(&samr_server, 130 rpc_host, 131 samrt_v1_0_c_ifspec, 132 protocol, mech, level) == 0) 133 { 134 printf ("Couldnt obtain RPC server binding. exiting.\n"); 135 exit(1); 136 } 137 138 139 /* 140 * Do the RPC call 141 */ 142 143 printf ("calling server\n"); 144 DCETHREAD_TRY 145 { 146 ntstatus = samrt_Connect(samr_server, NULL, 0, &handle); 147 } 148 DCETHREAD_CATCH_ALL(THIS_CATCH) 149 { 150 printf ("Exception caught from samrt_Connect\n"); 151 } 152 DCETHREAD_ENDTRY 153 154 155 156 /* 157 * Print the results 158 */ 159 160 if (ntstatus == 0) 161 { 162 printf ("got response from server. results: \n"); 163 printf("\tntstatus = %u\n", (unsigned int)(ntstatus)); 164 printf("\n===================================\n"); 165 166 } 167 168 if (ntstatus != 0) 169 chk_dce_err(ntstatus, "samrt_Connet()", "main()", 1); 170 171 mech_ctx = NULL; 172 rpc_binding_inq_security_context(samr_server, &authn_protocol, &mech_ctx, 173 &status); 174 175 /* 176 * Done. Now gracefully teardown the RPC binding to the server 177 */ 178 179 rpc_binding_free(&samr_server, &status); 180 exit(0); 181 182} 183 184/*========================================================================== 185 * 186 * get_client_rpc_binding() 187 * 188 *========================================================================== 189 * 190 * Gets a binding handle to an RPC interface. 191 * 192 * parameters: 193 * 194 * [in/out] binding_handle 195 * [in] hostname <- Internet hostname where server lives 196 * [in] interface_uuid <- DCE Interface UUID for service 197 * [in] protocol <- "udp", "tcp" or "any" 198 * 199 *==========================================================================*/ 200 201static int 202get_client_rpc_binding( 203 rpc_binding_handle_t * binding_handle, 204 const char * hostname, 205 rpc_if_handle_t interface_spec, 206 const char * protocol, 207 const char * mech, 208 const char * level) 209{ 210 char * resolved_binding; 211 char * printable_uuid ATTRIBUTE_UNUSED; 212 const char * protocol_family; 213 char partial_string_binding[128]; 214 char server_principal[128]; 215 rpc_if_id_t nonkeyword_interface ATTRIBUTE_UNUSED; 216 idl_uuid_t ifc_uuid ATTRIBUTE_UNUSED; 217 error_status_t status; 218 unsigned32 authn_protocol = rpc_c_authn_gss_negotiate; 219 unsigned32 authn_level = rpc_c_authn_level_connect; 220 221 /* 222 * create a string binding given the command line parameters and 223 * resolve it into a full binding handle using the endpoint mapper. 224 * The binding handle resolution is handled by the runtime library 225 */ 226 227 228 if (strcmp(protocol, "udp")==0) 229 protocol_family = "ncadg_ip_udp"; 230 else 231 protocol_family = "ncacn_ip_tcp"; 232 233 234 sprintf(partial_string_binding, "%s:%s[]", 235 protocol_family, 236 hostname); 237 238 rpc_binding_from_string_binding((unsigned char *)partial_string_binding, 239 binding_handle, 240 &status); 241 chk_dce_err(status, "string2binding()", "get_client_rpc_binding", 1); 242 243 /* 244 * Resolve the partial binding handle using the endpoint mapper 245 */ 246 247 rpc_ep_resolve_binding(*binding_handle, 248 interface_spec, 249 &status); 250 chk_dce_err(status, "rpc_ep_resolve_binding()", "get_client_rpc_binding", 1); 251 252/*TODO*/ sprintf(server_principal, "host/%s", 253 hostname); 254 255 if (strcmp(mech, "spnego") == 0) 256 authn_protocol = rpc_c_authn_gss_negotiate; 257 else if (strcmp(mech, "krb5") == 0) 258 authn_protocol = rpc_c_authn_gss_mskrb; 259 else { 260 printf("invalid mech[%s]\n", mech); 261 exit(1); 262 } 263 264 if (strcmp(level, "connect") == 0) 265 authn_level = rpc_c_authn_level_connect; 266 else if (strcmp(level, "sign") == 0) 267 authn_level = rpc_c_protect_level_pkt_integ; 268 else if (strcmp(level, "seal") == 0) 269 authn_level = rpc_c_protect_level_pkt_privacy; 270 else { 271 printf("invalid level[%s]\n", level); 272 exit(1); 273 } 274 275 rpc_binding_set_auth_info(*binding_handle, 276 (unsigned_char_p_t)server_principal, 277 authn_level, 278 authn_protocol, 279 NULL, 280 rpc_c_authz_name, 281 &status); 282 chk_dce_err(status, "rpc_binding_set_auth_info()", "get_client_rpc_binding", 1); 283 284/* 285 * Get a printable rendition of the binding handle and echo to 286 * the user. 287 */ 288 289 rpc_binding_to_string_binding(*binding_handle, 290 (unsigned char **)&resolved_binding, 291 &status); 292 chk_dce_err(status, "binding2string()", "get_client_rpc_binding", 1); 293 294 printf("fully resolving binding for server is: %s (mech[%s],level[%s])\n", 295 resolved_binding, mech, level); 296 297 298 return 1; 299} 300