1*11337SWilliam.Krier@Sun.COM /* 2*11337SWilliam.Krier@Sun.COM * CDDL HEADER START 3*11337SWilliam.Krier@Sun.COM * 4*11337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the 5*11337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License"). 6*11337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License. 7*11337SWilliam.Krier@Sun.COM * 8*11337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*11337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*11337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions 11*11337SWilliam.Krier@Sun.COM * and limitations under the License. 12*11337SWilliam.Krier@Sun.COM * 13*11337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*11337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*11337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*11337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*11337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*11337SWilliam.Krier@Sun.COM * 19*11337SWilliam.Krier@Sun.COM * CDDL HEADER END 20*11337SWilliam.Krier@Sun.COM */ 21*11337SWilliam.Krier@Sun.COM /* 22*11337SWilliam.Krier@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*11337SWilliam.Krier@Sun.COM * Use is subject to license terms. 24*11337SWilliam.Krier@Sun.COM */ 25*11337SWilliam.Krier@Sun.COM 26*11337SWilliam.Krier@Sun.COM /* 27*11337SWilliam.Krier@Sun.COM * Security Accounts Manager RPC (SAMR) server-side interface. 28*11337SWilliam.Krier@Sun.COM * 29*11337SWilliam.Krier@Sun.COM * The SAM is a hierarchical database: 30*11337SWilliam.Krier@Sun.COM * - If you want to talk to the SAM you need a SAM handle. 31*11337SWilliam.Krier@Sun.COM * - If you want to work with a domain, use the SAM handle. 32*11337SWilliam.Krier@Sun.COM * to obtain a domain handle. 33*11337SWilliam.Krier@Sun.COM * - Use domain handles to obtain user handles etc. 34*11337SWilliam.Krier@Sun.COM */ 35*11337SWilliam.Krier@Sun.COM 36*11337SWilliam.Krier@Sun.COM #include <strings.h> 37*11337SWilliam.Krier@Sun.COM #include <unistd.h> 38*11337SWilliam.Krier@Sun.COM #include <netdb.h> 39*11337SWilliam.Krier@Sun.COM #include <assert.h> 40*11337SWilliam.Krier@Sun.COM 41*11337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h> 42*11337SWilliam.Krier@Sun.COM #include <smbsrv/libmlrpc.h> 43*11337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h> 44*11337SWilliam.Krier@Sun.COM #include <smbsrv/ntstatus.h> 45*11337SWilliam.Krier@Sun.COM #include <smbsrv/nterror.h> 46*11337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h> 47*11337SWilliam.Krier@Sun.COM #include <smbsrv/nmpipes.h> 48*11337SWilliam.Krier@Sun.COM #include <smbsrv/ndl/samrpc.ndl> 49*11337SWilliam.Krier@Sun.COM #include <samlib.h> 50*11337SWilliam.Krier@Sun.COM 51*11337SWilliam.Krier@Sun.COM /* 52*11337SWilliam.Krier@Sun.COM * The keys associated with the various handles dispensed by the SAMR 53*11337SWilliam.Krier@Sun.COM * server. These keys can be used to validate client activity. 54*11337SWilliam.Krier@Sun.COM * These values are never passed over the wire so security shouldn't 55*11337SWilliam.Krier@Sun.COM * be an issue. 56*11337SWilliam.Krier@Sun.COM */ 57*11337SWilliam.Krier@Sun.COM typedef enum { 58*11337SWilliam.Krier@Sun.COM SAMR_KEY_NULL = 0, 59*11337SWilliam.Krier@Sun.COM SAMR_KEY_CONNECT, 60*11337SWilliam.Krier@Sun.COM SAMR_KEY_DOMAIN, 61*11337SWilliam.Krier@Sun.COM SAMR_KEY_USER, 62*11337SWilliam.Krier@Sun.COM SAMR_KEY_GROUP, 63*11337SWilliam.Krier@Sun.COM SAMR_KEY_ALIAS 64*11337SWilliam.Krier@Sun.COM } samr_key_t; 65*11337SWilliam.Krier@Sun.COM 66*11337SWilliam.Krier@Sun.COM typedef struct samr_keydata { 67*11337SWilliam.Krier@Sun.COM samr_key_t kd_key; 68*11337SWilliam.Krier@Sun.COM smb_domain_type_t kd_type; 69*11337SWilliam.Krier@Sun.COM DWORD kd_rid; 70*11337SWilliam.Krier@Sun.COM } samr_keydata_t; 71*11337SWilliam.Krier@Sun.COM 72*11337SWilliam.Krier@Sun.COM /* 73*11337SWilliam.Krier@Sun.COM * DomainDisplayUser All user objects (or those derived from user) with 74*11337SWilliam.Krier@Sun.COM * userAccountControl containing the UF_NORMAL_ACCOUNT bit. 75*11337SWilliam.Krier@Sun.COM * 76*11337SWilliam.Krier@Sun.COM * DomainDisplayMachine All user objects (or those derived from user) with 77*11337SWilliam.Krier@Sun.COM * userAccountControl containing the 78*11337SWilliam.Krier@Sun.COM * UF_WORKSTATION_TRUST_ACCOUNT or UF_SERVER_TRUST_ACCOUNT 79*11337SWilliam.Krier@Sun.COM * bit. 80*11337SWilliam.Krier@Sun.COM * 81*11337SWilliam.Krier@Sun.COM * DomainDisplayGroup All group objects (or those derived from group) with 82*11337SWilliam.Krier@Sun.COM * groupType equal to GROUP_TYPE_SECURITY_UNIVERSAL or 83*11337SWilliam.Krier@Sun.COM * GROUP_TYPE_SECURITY_ACCOUNT. 84*11337SWilliam.Krier@Sun.COM * 85*11337SWilliam.Krier@Sun.COM * DomainDisplayOemUser Same as DomainDisplayUser with OEM strings 86*11337SWilliam.Krier@Sun.COM * 87*11337SWilliam.Krier@Sun.COM * DomainDisplayOemGroup Same as DomainDisplayGroup with OEM strings 88*11337SWilliam.Krier@Sun.COM */ 89*11337SWilliam.Krier@Sun.COM typedef enum { 90*11337SWilliam.Krier@Sun.COM DomainDisplayUser = 1, 91*11337SWilliam.Krier@Sun.COM DomainDisplayMachine, 92*11337SWilliam.Krier@Sun.COM DomainDispalyGroup, 93*11337SWilliam.Krier@Sun.COM DomainDisplayOemUser, 94*11337SWilliam.Krier@Sun.COM DomainDisplayOemGroup 95*11337SWilliam.Krier@Sun.COM } samr_displvl_t; 96*11337SWilliam.Krier@Sun.COM 97*11337SWilliam.Krier@Sun.COM #define SAMR_VALID_DISPLEVEL(lvl) \ 98*11337SWilliam.Krier@Sun.COM (((lvl) >= DomainDisplayUser) && ((lvl) <= DomainDisplayOemGroup)) 99*11337SWilliam.Krier@Sun.COM 100*11337SWilliam.Krier@Sun.COM #define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser) 101*11337SWilliam.Krier@Sun.COM 102*11337SWilliam.Krier@Sun.COM static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_domain_type_t, 103*11337SWilliam.Krier@Sun.COM DWORD); 104*11337SWilliam.Krier@Sun.COM static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *); 105*11337SWilliam.Krier@Sun.COM static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t); 106*11337SWilliam.Krier@Sun.COM static int samr_call_stub(ndr_xa_t *mxa); 107*11337SWilliam.Krier@Sun.COM static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *, 108*11337SWilliam.Krier@Sun.COM ndr_xa_t *); 109*11337SWilliam.Krier@Sun.COM 110*11337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[]; 111*11337SWilliam.Krier@Sun.COM 112*11337SWilliam.Krier@Sun.COM static ndr_service_t samr_service = { 113*11337SWilliam.Krier@Sun.COM "SAMR", /* name */ 114*11337SWilliam.Krier@Sun.COM "Security Accounts Manager", /* desc */ 115*11337SWilliam.Krier@Sun.COM "\\samr", /* endpoint */ 116*11337SWilliam.Krier@Sun.COM PIPE_LSASS, /* sec_addr_port */ 117*11337SWilliam.Krier@Sun.COM "12345778-1234-abcd-ef00-0123456789ac", 1, /* abstract */ 118*11337SWilliam.Krier@Sun.COM NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */ 119*11337SWilliam.Krier@Sun.COM 0, /* no bind_instance_size */ 120*11337SWilliam.Krier@Sun.COM NULL, /* no bind_req() */ 121*11337SWilliam.Krier@Sun.COM NULL, /* no unbind_and_close() */ 122*11337SWilliam.Krier@Sun.COM samr_call_stub, /* call_stub() */ 123*11337SWilliam.Krier@Sun.COM &TYPEINFO(samr_interface), /* interface ti */ 124*11337SWilliam.Krier@Sun.COM samr_stub_table /* stub_table */ 125*11337SWilliam.Krier@Sun.COM }; 126*11337SWilliam.Krier@Sun.COM 127*11337SWilliam.Krier@Sun.COM /* 128*11337SWilliam.Krier@Sun.COM * samr_initialize 129*11337SWilliam.Krier@Sun.COM * 130*11337SWilliam.Krier@Sun.COM * This function registers the SAM RPC interface with the RPC runtime 131*11337SWilliam.Krier@Sun.COM * library. It must be called in order to use either the client side 132*11337SWilliam.Krier@Sun.COM * or the server side functions. 133*11337SWilliam.Krier@Sun.COM */ 134*11337SWilliam.Krier@Sun.COM void 135*11337SWilliam.Krier@Sun.COM samr_initialize(void) 136*11337SWilliam.Krier@Sun.COM { 137*11337SWilliam.Krier@Sun.COM (void) ndr_svc_register(&samr_service); 138*11337SWilliam.Krier@Sun.COM } 139*11337SWilliam.Krier@Sun.COM 140*11337SWilliam.Krier@Sun.COM /* 141*11337SWilliam.Krier@Sun.COM * Custom call_stub to set the stream string policy. 142*11337SWilliam.Krier@Sun.COM */ 143*11337SWilliam.Krier@Sun.COM static int 144*11337SWilliam.Krier@Sun.COM samr_call_stub(ndr_xa_t *mxa) 145*11337SWilliam.Krier@Sun.COM { 146*11337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->send_nds, NDS_F_NOTERM); 147*11337SWilliam.Krier@Sun.COM NDS_SETF(&mxa->recv_nds, NDS_F_NOTERM); 148*11337SWilliam.Krier@Sun.COM 149*11337SWilliam.Krier@Sun.COM return (ndr_generic_call_stub(mxa)); 150*11337SWilliam.Krier@Sun.COM } 151*11337SWilliam.Krier@Sun.COM 152*11337SWilliam.Krier@Sun.COM /* 153*11337SWilliam.Krier@Sun.COM * Handle allocation wrapper to setup the local context. 154*11337SWilliam.Krier@Sun.COM */ 155*11337SWilliam.Krier@Sun.COM static ndr_hdid_t * 156*11337SWilliam.Krier@Sun.COM samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type, 157*11337SWilliam.Krier@Sun.COM DWORD rid) 158*11337SWilliam.Krier@Sun.COM { 159*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 160*11337SWilliam.Krier@Sun.COM 161*11337SWilliam.Krier@Sun.COM if ((data = malloc(sizeof (samr_keydata_t))) == NULL) 162*11337SWilliam.Krier@Sun.COM return (NULL); 163*11337SWilliam.Krier@Sun.COM 164*11337SWilliam.Krier@Sun.COM data->kd_key = key; 165*11337SWilliam.Krier@Sun.COM data->kd_type = domain_type; 166*11337SWilliam.Krier@Sun.COM data->kd_rid = rid; 167*11337SWilliam.Krier@Sun.COM 168*11337SWilliam.Krier@Sun.COM return (ndr_hdalloc(mxa, data)); 169*11337SWilliam.Krier@Sun.COM } 170*11337SWilliam.Krier@Sun.COM 171*11337SWilliam.Krier@Sun.COM /* 172*11337SWilliam.Krier@Sun.COM * Handle deallocation wrapper to free the local context. 173*11337SWilliam.Krier@Sun.COM */ 174*11337SWilliam.Krier@Sun.COM static void 175*11337SWilliam.Krier@Sun.COM samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id) 176*11337SWilliam.Krier@Sun.COM { 177*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 178*11337SWilliam.Krier@Sun.COM 179*11337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) != NULL) { 180*11337SWilliam.Krier@Sun.COM free(hd->nh_data); 181*11337SWilliam.Krier@Sun.COM ndr_hdfree(mxa, id); 182*11337SWilliam.Krier@Sun.COM } 183*11337SWilliam.Krier@Sun.COM } 184*11337SWilliam.Krier@Sun.COM 185*11337SWilliam.Krier@Sun.COM /* 186*11337SWilliam.Krier@Sun.COM * Handle lookup wrapper to validate the local context. 187*11337SWilliam.Krier@Sun.COM */ 188*11337SWilliam.Krier@Sun.COM static ndr_handle_t * 189*11337SWilliam.Krier@Sun.COM samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key) 190*11337SWilliam.Krier@Sun.COM { 191*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 192*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 193*11337SWilliam.Krier@Sun.COM 194*11337SWilliam.Krier@Sun.COM if ((hd = ndr_hdlookup(mxa, id)) == NULL) 195*11337SWilliam.Krier@Sun.COM return (NULL); 196*11337SWilliam.Krier@Sun.COM 197*11337SWilliam.Krier@Sun.COM if ((data = (samr_keydata_t *)hd->nh_data) == NULL) 198*11337SWilliam.Krier@Sun.COM return (NULL); 199*11337SWilliam.Krier@Sun.COM 200*11337SWilliam.Krier@Sun.COM if (data->kd_key != key) 201*11337SWilliam.Krier@Sun.COM return (NULL); 202*11337SWilliam.Krier@Sun.COM 203*11337SWilliam.Krier@Sun.COM return (hd); 204*11337SWilliam.Krier@Sun.COM } 205*11337SWilliam.Krier@Sun.COM 206*11337SWilliam.Krier@Sun.COM /* 207*11337SWilliam.Krier@Sun.COM * samr_s_ConnectAnon 208*11337SWilliam.Krier@Sun.COM * 209*11337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. We don't 210*11337SWilliam.Krier@Sun.COM * support any form of update request and our database doesn't 211*11337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in 212*11337SWilliam.Krier@Sun.COM * doing any access access checking here. 213*11337SWilliam.Krier@Sun.COM * 214*11337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 215*11337SWilliam.Krier@Sun.COM */ 216*11337SWilliam.Krier@Sun.COM static int 217*11337SWilliam.Krier@Sun.COM samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa) 218*11337SWilliam.Krier@Sun.COM { 219*11337SWilliam.Krier@Sun.COM struct samr_ConnectAnon *param = arg; 220*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 221*11337SWilliam.Krier@Sun.COM 222*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 223*11337SWilliam.Krier@Sun.COM if (id) { 224*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 225*11337SWilliam.Krier@Sun.COM param->status = 0; 226*11337SWilliam.Krier@Sun.COM } else { 227*11337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 228*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 229*11337SWilliam.Krier@Sun.COM } 230*11337SWilliam.Krier@Sun.COM 231*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 232*11337SWilliam.Krier@Sun.COM } 233*11337SWilliam.Krier@Sun.COM 234*11337SWilliam.Krier@Sun.COM /* 235*11337SWilliam.Krier@Sun.COM * samr_s_CloseHandle 236*11337SWilliam.Krier@Sun.COM * 237*11337SWilliam.Krier@Sun.COM * Close the SAM interface specified by the handle. 238*11337SWilliam.Krier@Sun.COM * Free the handle and zero out the result handle for the client. 239*11337SWilliam.Krier@Sun.COM */ 240*11337SWilliam.Krier@Sun.COM static int 241*11337SWilliam.Krier@Sun.COM samr_s_CloseHandle(void *arg, ndr_xa_t *mxa) 242*11337SWilliam.Krier@Sun.COM { 243*11337SWilliam.Krier@Sun.COM struct samr_CloseHandle *param = arg; 244*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 245*11337SWilliam.Krier@Sun.COM 246*11337SWilliam.Krier@Sun.COM samr_hdfree(mxa, id); 247*11337SWilliam.Krier@Sun.COM 248*11337SWilliam.Krier@Sun.COM bzero(¶m->result_handle, sizeof (samr_handle_t)); 249*11337SWilliam.Krier@Sun.COM param->status = 0; 250*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 251*11337SWilliam.Krier@Sun.COM } 252*11337SWilliam.Krier@Sun.COM 253*11337SWilliam.Krier@Sun.COM /* 254*11337SWilliam.Krier@Sun.COM * samr_s_LookupDomain 255*11337SWilliam.Krier@Sun.COM * 256*11337SWilliam.Krier@Sun.COM * This is a request to map a domain name to a domain SID. We can map 257*11337SWilliam.Krier@Sun.COM * the primary domain name, our local domain name (hostname) and the 258*11337SWilliam.Krier@Sun.COM * builtin domain names to the appropriate SID. Anything else will be 259*11337SWilliam.Krier@Sun.COM * rejected. 260*11337SWilliam.Krier@Sun.COM */ 261*11337SWilliam.Krier@Sun.COM static int 262*11337SWilliam.Krier@Sun.COM samr_s_LookupDomain(void *arg, ndr_xa_t *mxa) 263*11337SWilliam.Krier@Sun.COM { 264*11337SWilliam.Krier@Sun.COM struct samr_LookupDomain *param = arg; 265*11337SWilliam.Krier@Sun.COM char *domain_name; 266*11337SWilliam.Krier@Sun.COM smb_domain_t di; 267*11337SWilliam.Krier@Sun.COM 268*11337SWilliam.Krier@Sun.COM if ((domain_name = (char *)param->domain_name.str) == NULL) { 269*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 270*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER); 271*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 272*11337SWilliam.Krier@Sun.COM } 273*11337SWilliam.Krier@Sun.COM 274*11337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_name(domain_name, &di)) { 275*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 276*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN); 277*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 278*11337SWilliam.Krier@Sun.COM } 279*11337SWilliam.Krier@Sun.COM 280*11337SWilliam.Krier@Sun.COM param->sid = (struct samr_sid *)NDR_SIDDUP(mxa, di.di_binsid); 281*11337SWilliam.Krier@Sun.COM if (param->sid == NULL) { 282*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupDomain)); 283*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 284*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 285*11337SWilliam.Krier@Sun.COM } 286*11337SWilliam.Krier@Sun.COM 287*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 288*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 289*11337SWilliam.Krier@Sun.COM } 290*11337SWilliam.Krier@Sun.COM 291*11337SWilliam.Krier@Sun.COM /* 292*11337SWilliam.Krier@Sun.COM * samr_s_EnumLocalDomains 293*11337SWilliam.Krier@Sun.COM * 294*11337SWilliam.Krier@Sun.COM * This is a request for the local domains supported by this server. 295*11337SWilliam.Krier@Sun.COM * All we do here is validate the handle and set the status. The real 296*11337SWilliam.Krier@Sun.COM * work is done in samr_s_enum_local_domains. 297*11337SWilliam.Krier@Sun.COM */ 298*11337SWilliam.Krier@Sun.COM static int 299*11337SWilliam.Krier@Sun.COM samr_s_EnumLocalDomains(void *arg, ndr_xa_t *mxa) 300*11337SWilliam.Krier@Sun.COM { 301*11337SWilliam.Krier@Sun.COM struct samr_EnumLocalDomain *param = arg; 302*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 303*11337SWilliam.Krier@Sun.COM DWORD status; 304*11337SWilliam.Krier@Sun.COM 305*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) 306*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 307*11337SWilliam.Krier@Sun.COM else 308*11337SWilliam.Krier@Sun.COM status = samr_s_enum_local_domains(param, mxa); 309*11337SWilliam.Krier@Sun.COM 310*11337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 311*11337SWilliam.Krier@Sun.COM param->enum_context = param->info->entries_read; 312*11337SWilliam.Krier@Sun.COM param->total_entries = param->info->entries_read; 313*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 314*11337SWilliam.Krier@Sun.COM } else { 315*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumLocalDomain)); 316*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 317*11337SWilliam.Krier@Sun.COM } 318*11337SWilliam.Krier@Sun.COM 319*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 320*11337SWilliam.Krier@Sun.COM } 321*11337SWilliam.Krier@Sun.COM 322*11337SWilliam.Krier@Sun.COM 323*11337SWilliam.Krier@Sun.COM /* 324*11337SWilliam.Krier@Sun.COM * samr_s_enum_local_domains 325*11337SWilliam.Krier@Sun.COM * 326*11337SWilliam.Krier@Sun.COM * This function should only be called via samr_s_EnumLocalDomains to 327*11337SWilliam.Krier@Sun.COM * ensure that the appropriate validation is performed. We will answer 328*11337SWilliam.Krier@Sun.COM * queries about two domains: the local domain, synonymous with the 329*11337SWilliam.Krier@Sun.COM * local hostname, and the BUILTIN domain. So we return these two 330*11337SWilliam.Krier@Sun.COM * strings. 331*11337SWilliam.Krier@Sun.COM * 332*11337SWilliam.Krier@Sun.COM * Returns NT status values. 333*11337SWilliam.Krier@Sun.COM */ 334*11337SWilliam.Krier@Sun.COM static DWORD 335*11337SWilliam.Krier@Sun.COM samr_s_enum_local_domains(struct samr_EnumLocalDomain *param, 336*11337SWilliam.Krier@Sun.COM ndr_xa_t *mxa) 337*11337SWilliam.Krier@Sun.COM { 338*11337SWilliam.Krier@Sun.COM struct samr_LocalDomainInfo *info; 339*11337SWilliam.Krier@Sun.COM struct samr_LocalDomainEntry *entry; 340*11337SWilliam.Krier@Sun.COM char *hostname; 341*11337SWilliam.Krier@Sun.COM 342*11337SWilliam.Krier@Sun.COM hostname = NDR_MALLOC(mxa, NETBIOS_NAME_SZ); 343*11337SWilliam.Krier@Sun.COM if (hostname == NULL) 344*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 345*11337SWilliam.Krier@Sun.COM 346*11337SWilliam.Krier@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) 347*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 348*11337SWilliam.Krier@Sun.COM 349*11337SWilliam.Krier@Sun.COM entry = NDR_NEWN(mxa, struct samr_LocalDomainEntry, 2); 350*11337SWilliam.Krier@Sun.COM if (entry == NULL) 351*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 352*11337SWilliam.Krier@Sun.COM 353*11337SWilliam.Krier@Sun.COM bzero(entry, (sizeof (struct samr_LocalDomainEntry) * 2)); 354*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, hostname, (ndr_mstring_t *)&entry[0].name); 355*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Builtin", (ndr_mstring_t *)&entry[1].name); 356*11337SWilliam.Krier@Sun.COM 357*11337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_LocalDomainInfo); 358*11337SWilliam.Krier@Sun.COM if (info == NULL) 359*11337SWilliam.Krier@Sun.COM return (NT_STATUS_NO_MEMORY); 360*11337SWilliam.Krier@Sun.COM 361*11337SWilliam.Krier@Sun.COM info->entries_read = 2; 362*11337SWilliam.Krier@Sun.COM info->entry = entry; 363*11337SWilliam.Krier@Sun.COM param->info = info; 364*11337SWilliam.Krier@Sun.COM return (NT_STATUS_SUCCESS); 365*11337SWilliam.Krier@Sun.COM } 366*11337SWilliam.Krier@Sun.COM 367*11337SWilliam.Krier@Sun.COM /* 368*11337SWilliam.Krier@Sun.COM * samr_s_OpenDomain 369*11337SWilliam.Krier@Sun.COM * 370*11337SWilliam.Krier@Sun.COM * This is a request to open a domain within the local SAM database. 371*11337SWilliam.Krier@Sun.COM * The caller must supply a valid connect handle. 372*11337SWilliam.Krier@Sun.COM * We return a handle to be used to access objects within this domain. 373*11337SWilliam.Krier@Sun.COM */ 374*11337SWilliam.Krier@Sun.COM static int 375*11337SWilliam.Krier@Sun.COM samr_s_OpenDomain(void *arg, ndr_xa_t *mxa) 376*11337SWilliam.Krier@Sun.COM { 377*11337SWilliam.Krier@Sun.COM struct samr_OpenDomain *param = arg; 378*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 379*11337SWilliam.Krier@Sun.COM smb_domain_t domain; 380*11337SWilliam.Krier@Sun.COM 381*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) { 382*11337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 383*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 384*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 385*11337SWilliam.Krier@Sun.COM } 386*11337SWilliam.Krier@Sun.COM 387*11337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) { 388*11337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 389*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 390*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 391*11337SWilliam.Krier@Sun.COM } 392*11337SWilliam.Krier@Sun.COM 393*11337SWilliam.Krier@Sun.COM if ((domain.di_type != SMB_DOMAIN_BUILTIN) && 394*11337SWilliam.Krier@Sun.COM (domain.di_type != SMB_DOMAIN_LOCAL)) { 395*11337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 396*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 397*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 398*11337SWilliam.Krier@Sun.COM } 399*11337SWilliam.Krier@Sun.COM 400*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain.di_type, 0); 401*11337SWilliam.Krier@Sun.COM if (id) { 402*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->domain_handle, sizeof (samr_handle_t)); 403*11337SWilliam.Krier@Sun.COM param->status = 0; 404*11337SWilliam.Krier@Sun.COM } else { 405*11337SWilliam.Krier@Sun.COM bzero(¶m->domain_handle, sizeof (samr_handle_t)); 406*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 407*11337SWilliam.Krier@Sun.COM } 408*11337SWilliam.Krier@Sun.COM 409*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 410*11337SWilliam.Krier@Sun.COM } 411*11337SWilliam.Krier@Sun.COM 412*11337SWilliam.Krier@Sun.COM /* 413*11337SWilliam.Krier@Sun.COM * samr_s_QueryDomainInfo 414*11337SWilliam.Krier@Sun.COM * 415*11337SWilliam.Krier@Sun.COM * The caller should pass a domain handle. 416*11337SWilliam.Krier@Sun.COM * 417*11337SWilliam.Krier@Sun.COM * Windows 95 Server Manager sends requests for levels 6 and 7 when 418*11337SWilliam.Krier@Sun.COM * the services menu item is selected. Level 2 is basically for getting 419*11337SWilliam.Krier@Sun.COM * number of users, groups, and aliases in a domain. 420*11337SWilliam.Krier@Sun.COM * We have no information on what the various information levels mean. 421*11337SWilliam.Krier@Sun.COM */ 422*11337SWilliam.Krier@Sun.COM static int 423*11337SWilliam.Krier@Sun.COM samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa) 424*11337SWilliam.Krier@Sun.COM { 425*11337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfo *param = arg; 426*11337SWilliam.Krier@Sun.COM struct samr_QueryDomainInfoRes *info; 427*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 428*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 429*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 430*11337SWilliam.Krier@Sun.COM char *domain; 431*11337SWilliam.Krier@Sun.COM char hostname[NETBIOS_NAME_SZ]; 432*11337SWilliam.Krier@Sun.COM int alias_cnt, user_cnt; 433*11337SWilliam.Krier@Sun.COM int rc = 0; 434*11337SWilliam.Krier@Sun.COM 435*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 436*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 437*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 438*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 439*11337SWilliam.Krier@Sun.COM } 440*11337SWilliam.Krier@Sun.COM 441*11337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_QueryDomainInfoRes); 442*11337SWilliam.Krier@Sun.COM if (info == NULL) { 443*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 444*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 445*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 446*11337SWilliam.Krier@Sun.COM } 447*11337SWilliam.Krier@Sun.COM info->switch_value = param->info_level; 448*11337SWilliam.Krier@Sun.COM param->info = info; 449*11337SWilliam.Krier@Sun.COM 450*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 451*11337SWilliam.Krier@Sun.COM 452*11337SWilliam.Krier@Sun.COM switch (data->kd_type) { 453*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 454*11337SWilliam.Krier@Sun.COM domain = "BUILTIN"; 455*11337SWilliam.Krier@Sun.COM user_cnt = 0; 456*11337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 457*11337SWilliam.Krier@Sun.COM break; 458*11337SWilliam.Krier@Sun.COM 459*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 460*11337SWilliam.Krier@Sun.COM rc = smb_getnetbiosname(hostname, sizeof (hostname)); 461*11337SWilliam.Krier@Sun.COM if (rc == 0) { 462*11337SWilliam.Krier@Sun.COM domain = hostname; 463*11337SWilliam.Krier@Sun.COM user_cnt = smb_sam_usr_cnt(); 464*11337SWilliam.Krier@Sun.COM alias_cnt = smb_sam_grp_cnt(data->kd_type); 465*11337SWilliam.Krier@Sun.COM } 466*11337SWilliam.Krier@Sun.COM break; 467*11337SWilliam.Krier@Sun.COM 468*11337SWilliam.Krier@Sun.COM default: 469*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 470*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 471*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 472*11337SWilliam.Krier@Sun.COM } 473*11337SWilliam.Krier@Sun.COM 474*11337SWilliam.Krier@Sun.COM if (rc != 0) { 475*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 476*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 477*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 478*11337SWilliam.Krier@Sun.COM } 479*11337SWilliam.Krier@Sun.COM 480*11337SWilliam.Krier@Sun.COM switch (param->info_level) { 481*11337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_6: 482*11337SWilliam.Krier@Sun.COM info->ru.info6.unknown1 = 0x00000000; 483*11337SWilliam.Krier@Sun.COM info->ru.info6.unknown2 = 0x00147FB0; 484*11337SWilliam.Krier@Sun.COM info->ru.info6.unknown3 = 0x00000000; 485*11337SWilliam.Krier@Sun.COM info->ru.info6.unknown4 = 0x00000000; 486*11337SWilliam.Krier@Sun.COM info->ru.info6.unknown5 = 0x00000000; 487*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 488*11337SWilliam.Krier@Sun.COM break; 489*11337SWilliam.Krier@Sun.COM 490*11337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_7: 491*11337SWilliam.Krier@Sun.COM info->ru.info7.unknown1 = 0x00000003; 492*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 493*11337SWilliam.Krier@Sun.COM break; 494*11337SWilliam.Krier@Sun.COM 495*11337SWilliam.Krier@Sun.COM case SAMR_QUERY_DOMAIN_INFO_2: 496*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown1 = 0x00000000; 497*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown2 = 0x80000000; 498*11337SWilliam.Krier@Sun.COM 499*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 500*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s1)); 501*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, domain, 502*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.domain)); 503*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "", 504*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&(info->ru.info2.s2)); 505*11337SWilliam.Krier@Sun.COM 506*11337SWilliam.Krier@Sun.COM info->ru.info2.sequence_num = 0x0000002B; 507*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown3 = 0x00000000; 508*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown4 = 0x00000001; 509*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown5 = 0x00000003; 510*11337SWilliam.Krier@Sun.COM info->ru.info2.unknown6 = 0x00000001; 511*11337SWilliam.Krier@Sun.COM info->ru.info2.num_users = user_cnt; 512*11337SWilliam.Krier@Sun.COM info->ru.info2.num_groups = 0; 513*11337SWilliam.Krier@Sun.COM info->ru.info2.num_aliases = alias_cnt; 514*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 515*11337SWilliam.Krier@Sun.COM break; 516*11337SWilliam.Krier@Sun.COM 517*11337SWilliam.Krier@Sun.COM default: 518*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDomainInfo)); 519*11337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 520*11337SWilliam.Krier@Sun.COM }; 521*11337SWilliam.Krier@Sun.COM 522*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 523*11337SWilliam.Krier@Sun.COM } 524*11337SWilliam.Krier@Sun.COM 525*11337SWilliam.Krier@Sun.COM /* 526*11337SWilliam.Krier@Sun.COM * Looks up the given name in the specified domain which could 527*11337SWilliam.Krier@Sun.COM * be either the built-in or local domain. 528*11337SWilliam.Krier@Sun.COM * 529*11337SWilliam.Krier@Sun.COM * CAVEAT: this function should be able to handle a list of 530*11337SWilliam.Krier@Sun.COM * names but currently it can only handle one name at a time. 531*11337SWilliam.Krier@Sun.COM */ 532*11337SWilliam.Krier@Sun.COM static int 533*11337SWilliam.Krier@Sun.COM samr_s_LookupNames(void *arg, ndr_xa_t *mxa) 534*11337SWilliam.Krier@Sun.COM { 535*11337SWilliam.Krier@Sun.COM struct samr_LookupNames *param = arg; 536*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 537*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 538*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 539*11337SWilliam.Krier@Sun.COM smb_account_t account; 540*11337SWilliam.Krier@Sun.COM smb_wka_t *wka; 541*11337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS; 542*11337SWilliam.Krier@Sun.COM 543*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) 544*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 545*11337SWilliam.Krier@Sun.COM 546*11337SWilliam.Krier@Sun.COM if (param->n_entry != 1) 547*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 548*11337SWilliam.Krier@Sun.COM 549*11337SWilliam.Krier@Sun.COM if (param->name.str == NULL) { 550*11337SWilliam.Krier@Sun.COM /* 551*11337SWilliam.Krier@Sun.COM * Windows NT returns NT_STATUS_NONE_MAPPED. 552*11337SWilliam.Krier@Sun.COM * Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME. 553*11337SWilliam.Krier@Sun.COM */ 554*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NONE_MAPPED; 555*11337SWilliam.Krier@Sun.COM } 556*11337SWilliam.Krier@Sun.COM 557*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) { 558*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 559*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 560*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 561*11337SWilliam.Krier@Sun.COM } 562*11337SWilliam.Krier@Sun.COM 563*11337SWilliam.Krier@Sun.COM param->rids.rid = NDR_NEW(mxa, DWORD); 564*11337SWilliam.Krier@Sun.COM param->rid_types.rid_type = NDR_NEW(mxa, DWORD); 565*11337SWilliam.Krier@Sun.COM 566*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 567*11337SWilliam.Krier@Sun.COM 568*11337SWilliam.Krier@Sun.COM switch (data->kd_type) { 569*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 570*11337SWilliam.Krier@Sun.COM wka = smb_wka_lookup_name((char *)param->name.str); 571*11337SWilliam.Krier@Sun.COM if (wka != NULL) { 572*11337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 573*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(wka->wka_binsid, 574*11337SWilliam.Krier@Sun.COM ¶m->rids.rid[0]); 575*11337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 576*11337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = wka->wka_type; 577*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 578*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 579*11337SWilliam.Krier@Sun.COM } 580*11337SWilliam.Krier@Sun.COM break; 581*11337SWilliam.Krier@Sun.COM 582*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 583*11337SWilliam.Krier@Sun.COM status = smb_sam_lookup_name(NULL, (char *)param->name.str, 584*11337SWilliam.Krier@Sun.COM SidTypeUnknown, &account); 585*11337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) { 586*11337SWilliam.Krier@Sun.COM param->rids.n_entry = 1; 587*11337SWilliam.Krier@Sun.COM param->rids.rid[0] = account.a_rid; 588*11337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 1; 589*11337SWilliam.Krier@Sun.COM param->rid_types.rid_type[0] = account.a_type; 590*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 591*11337SWilliam.Krier@Sun.COM smb_account_free(&account); 592*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 593*11337SWilliam.Krier@Sun.COM } 594*11337SWilliam.Krier@Sun.COM break; 595*11337SWilliam.Krier@Sun.COM 596*11337SWilliam.Krier@Sun.COM default: 597*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_LookupNames)); 598*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 599*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 600*11337SWilliam.Krier@Sun.COM } 601*11337SWilliam.Krier@Sun.COM 602*11337SWilliam.Krier@Sun.COM param->rids.n_entry = 0; 603*11337SWilliam.Krier@Sun.COM param->rid_types.n_entry = 0; 604*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED); 605*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 606*11337SWilliam.Krier@Sun.COM } 607*11337SWilliam.Krier@Sun.COM 608*11337SWilliam.Krier@Sun.COM /* 609*11337SWilliam.Krier@Sun.COM * samr_s_OpenUser 610*11337SWilliam.Krier@Sun.COM * 611*11337SWilliam.Krier@Sun.COM * This is a request to open a user within a specified domain in the 612*11337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 613*11337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The user is 614*11337SWilliam.Krier@Sun.COM * specified by the rid in the request. 615*11337SWilliam.Krier@Sun.COM */ 616*11337SWilliam.Krier@Sun.COM static int 617*11337SWilliam.Krier@Sun.COM samr_s_OpenUser(void *arg, ndr_xa_t *mxa) 618*11337SWilliam.Krier@Sun.COM { 619*11337SWilliam.Krier@Sun.COM struct samr_OpenUser *param = arg; 620*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 621*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 622*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 623*11337SWilliam.Krier@Sun.COM 624*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 625*11337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 626*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 627*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 628*11337SWilliam.Krier@Sun.COM } 629*11337SWilliam.Krier@Sun.COM 630*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 631*11337SWilliam.Krier@Sun.COM 632*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid); 633*11337SWilliam.Krier@Sun.COM if (id == NULL) { 634*11337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 635*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 636*11337SWilliam.Krier@Sun.COM } else { 637*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->user_handle, sizeof (samr_handle_t)); 638*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 639*11337SWilliam.Krier@Sun.COM } 640*11337SWilliam.Krier@Sun.COM 641*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 642*11337SWilliam.Krier@Sun.COM } 643*11337SWilliam.Krier@Sun.COM 644*11337SWilliam.Krier@Sun.COM /* 645*11337SWilliam.Krier@Sun.COM * samr_s_DeleteUser 646*11337SWilliam.Krier@Sun.COM * 647*11337SWilliam.Krier@Sun.COM * Request to delete a user within a specified domain in the local 648*11337SWilliam.Krier@Sun.COM * SAM database. The caller should supply a valid user handle. 649*11337SWilliam.Krier@Sun.COM */ 650*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 651*11337SWilliam.Krier@Sun.COM static int 652*11337SWilliam.Krier@Sun.COM samr_s_DeleteUser(void *arg, ndr_xa_t *mxa) 653*11337SWilliam.Krier@Sun.COM { 654*11337SWilliam.Krier@Sun.COM struct samr_DeleteUser *param = arg; 655*11337SWilliam.Krier@Sun.COM 656*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteUser)); 657*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 658*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 659*11337SWilliam.Krier@Sun.COM } 660*11337SWilliam.Krier@Sun.COM 661*11337SWilliam.Krier@Sun.COM /* 662*11337SWilliam.Krier@Sun.COM * samr_s_QueryUserInfo 663*11337SWilliam.Krier@Sun.COM * 664*11337SWilliam.Krier@Sun.COM * Returns: 665*11337SWilliam.Krier@Sun.COM * NT_STATUS_SUCCESS 666*11337SWilliam.Krier@Sun.COM * NT_STATUS_ACCESS_DENIED 667*11337SWilliam.Krier@Sun.COM * NT_STATUS_INVALID_INFO_CLASS 668*11337SWilliam.Krier@Sun.COM */ 669*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 670*11337SWilliam.Krier@Sun.COM static int 671*11337SWilliam.Krier@Sun.COM samr_s_QueryUserInfo(void *arg, ndr_xa_t *mxa) 672*11337SWilliam.Krier@Sun.COM { 673*11337SWilliam.Krier@Sun.COM static uint16_t owf_buf[8]; 674*11337SWilliam.Krier@Sun.COM static uint8_t hour_buf[SAMR_SET_USER_HOURS_SZ]; 675*11337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo *param = arg; 676*11337SWilliam.Krier@Sun.COM struct samr_QueryUserInfo21 *all_info; 677*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 678*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 679*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 680*11337SWilliam.Krier@Sun.COM smb_domain_t di; 681*11337SWilliam.Krier@Sun.COM smb_account_t account; 682*11337SWilliam.Krier@Sun.COM smb_sid_t *sid; 683*11337SWilliam.Krier@Sun.COM uint32_t status; 684*11337SWilliam.Krier@Sun.COM 685*11337SWilliam.Krier@Sun.COM id = (ndr_hdid_t *)¶m->user_handle; 686*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 687*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 688*11337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 689*11337SWilliam.Krier@Sun.COM } 690*11337SWilliam.Krier@Sun.COM 691*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 692*11337SWilliam.Krier@Sun.COM 693*11337SWilliam.Krier@Sun.COM if (param->switch_value != SAMR_QUERY_USER_ALL_INFO) { 694*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 695*11337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 696*11337SWilliam.Krier@Sun.COM } 697*11337SWilliam.Krier@Sun.COM 698*11337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di)) { 699*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 700*11337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 701*11337SWilliam.Krier@Sun.COM } 702*11337SWilliam.Krier@Sun.COM 703*11337SWilliam.Krier@Sun.COM if ((sid = smb_sid_splice(di.di_binsid, data->kd_rid)) == NULL) { 704*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 705*11337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 706*11337SWilliam.Krier@Sun.COM } 707*11337SWilliam.Krier@Sun.COM 708*11337SWilliam.Krier@Sun.COM if (smb_sam_lookup_sid(sid, &account) != NT_STATUS_SUCCESS) { 709*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 710*11337SWilliam.Krier@Sun.COM goto QueryUserInfoError; 711*11337SWilliam.Krier@Sun.COM } 712*11337SWilliam.Krier@Sun.COM 713*11337SWilliam.Krier@Sun.COM all_info = ¶m->ru.info21; 714*11337SWilliam.Krier@Sun.COM bzero(all_info, sizeof (struct samr_QueryUserInfo21)); 715*11337SWilliam.Krier@Sun.COM 716*11337SWilliam.Krier@Sun.COM all_info->WhichFields = SAMR_USER_ALL_USERNAME | SAMR_USER_ALL_USERID; 717*11337SWilliam.Krier@Sun.COM 718*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, account.a_name, 719*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&all_info->UserName); 720*11337SWilliam.Krier@Sun.COM all_info->UserId = data->kd_rid; 721*11337SWilliam.Krier@Sun.COM 722*11337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.length = 16; 723*11337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.maxlen = 16; 724*11337SWilliam.Krier@Sun.COM all_info->LmOwfPassword.buf = owf_buf; 725*11337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.length = 16; 726*11337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.maxlen = 16; 727*11337SWilliam.Krier@Sun.COM all_info->NtOwfPassword.buf = owf_buf; 728*11337SWilliam.Krier@Sun.COM all_info->LogonHours.units_per_week = SAMR_HOURS_PER_WEEK; 729*11337SWilliam.Krier@Sun.COM all_info->LogonHours.hours = hour_buf; 730*11337SWilliam.Krier@Sun.COM 731*11337SWilliam.Krier@Sun.COM param->address = 1; 732*11337SWilliam.Krier@Sun.COM param->switch_index = SAMR_QUERY_USER_ALL_INFO; 733*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 734*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 735*11337SWilliam.Krier@Sun.COM 736*11337SWilliam.Krier@Sun.COM QueryUserInfoError: 737*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserInfo)); 738*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 739*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 740*11337SWilliam.Krier@Sun.COM } 741*11337SWilliam.Krier@Sun.COM 742*11337SWilliam.Krier@Sun.COM /* 743*11337SWilliam.Krier@Sun.COM * samr_s_QueryUserGroups 744*11337SWilliam.Krier@Sun.COM * 745*11337SWilliam.Krier@Sun.COM * Request the list of groups of which a user is a member. 746*11337SWilliam.Krier@Sun.COM * The user is identified from the handle, which contains an 747*11337SWilliam.Krier@Sun.COM * rid in the discriminator field. Note that this is a local user. 748*11337SWilliam.Krier@Sun.COM */ 749*11337SWilliam.Krier@Sun.COM static int 750*11337SWilliam.Krier@Sun.COM samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa) 751*11337SWilliam.Krier@Sun.COM { 752*11337SWilliam.Krier@Sun.COM struct samr_QueryUserGroups *param = arg; 753*11337SWilliam.Krier@Sun.COM struct samr_UserGroupInfo *info; 754*11337SWilliam.Krier@Sun.COM struct samr_UserGroups *group; 755*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->user_handle; 756*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 757*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 758*11337SWilliam.Krier@Sun.COM smb_sid_t *user_sid = NULL; 759*11337SWilliam.Krier@Sun.COM smb_group_t grp; 760*11337SWilliam.Krier@Sun.COM smb_giter_t gi; 761*11337SWilliam.Krier@Sun.COM smb_domain_t di; 762*11337SWilliam.Krier@Sun.COM uint32_t status; 763*11337SWilliam.Krier@Sun.COM int size; 764*11337SWilliam.Krier@Sun.COM int ngrp_max; 765*11337SWilliam.Krier@Sun.COM 766*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) { 767*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 768*11337SWilliam.Krier@Sun.COM goto query_error; 769*11337SWilliam.Krier@Sun.COM } 770*11337SWilliam.Krier@Sun.COM 771*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 772*11337SWilliam.Krier@Sun.COM switch (data->kd_type) { 773*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 774*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 775*11337SWilliam.Krier@Sun.COM if (!smb_domain_lookup_type(data->kd_type, &di)) { 776*11337SWilliam.Krier@Sun.COM status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 777*11337SWilliam.Krier@Sun.COM goto query_error; 778*11337SWilliam.Krier@Sun.COM } 779*11337SWilliam.Krier@Sun.COM break; 780*11337SWilliam.Krier@Sun.COM default: 781*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 782*11337SWilliam.Krier@Sun.COM goto query_error; 783*11337SWilliam.Krier@Sun.COM } 784*11337SWilliam.Krier@Sun.COM 785*11337SWilliam.Krier@Sun.COM user_sid = smb_sid_splice(di.di_binsid, data->kd_rid); 786*11337SWilliam.Krier@Sun.COM if (user_sid == NULL) { 787*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 788*11337SWilliam.Krier@Sun.COM goto query_error; 789*11337SWilliam.Krier@Sun.COM } 790*11337SWilliam.Krier@Sun.COM 791*11337SWilliam.Krier@Sun.COM info = NDR_NEW(mxa, struct samr_UserGroupInfo); 792*11337SWilliam.Krier@Sun.COM if (info == NULL) { 793*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 794*11337SWilliam.Krier@Sun.COM goto query_error; 795*11337SWilliam.Krier@Sun.COM } 796*11337SWilliam.Krier@Sun.COM bzero(info, sizeof (struct samr_UserGroupInfo)); 797*11337SWilliam.Krier@Sun.COM 798*11337SWilliam.Krier@Sun.COM size = 32 * 1024; 799*11337SWilliam.Krier@Sun.COM info->groups = NDR_MALLOC(mxa, size); 800*11337SWilliam.Krier@Sun.COM if (info->groups == NULL) { 801*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 802*11337SWilliam.Krier@Sun.COM goto query_error; 803*11337SWilliam.Krier@Sun.COM } 804*11337SWilliam.Krier@Sun.COM ngrp_max = size / sizeof (struct samr_UserGroups); 805*11337SWilliam.Krier@Sun.COM 806*11337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 807*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 808*11337SWilliam.Krier@Sun.COM goto query_error; 809*11337SWilliam.Krier@Sun.COM } 810*11337SWilliam.Krier@Sun.COM 811*11337SWilliam.Krier@Sun.COM info->n_entry = 0; 812*11337SWilliam.Krier@Sun.COM group = info->groups; 813*11337SWilliam.Krier@Sun.COM while ((info->n_entry < ngrp_max) && 814*11337SWilliam.Krier@Sun.COM (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) { 815*11337SWilliam.Krier@Sun.COM if (smb_lgrp_is_member(&grp, user_sid)) { 816*11337SWilliam.Krier@Sun.COM group->rid = grp.sg_rid; 817*11337SWilliam.Krier@Sun.COM group->attr = grp.sg_attr; 818*11337SWilliam.Krier@Sun.COM group++; 819*11337SWilliam.Krier@Sun.COM info->n_entry++; 820*11337SWilliam.Krier@Sun.COM } 821*11337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 822*11337SWilliam.Krier@Sun.COM } 823*11337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 824*11337SWilliam.Krier@Sun.COM 825*11337SWilliam.Krier@Sun.COM free(user_sid); 826*11337SWilliam.Krier@Sun.COM param->info = info; 827*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 828*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 829*11337SWilliam.Krier@Sun.COM 830*11337SWilliam.Krier@Sun.COM query_error: 831*11337SWilliam.Krier@Sun.COM free(user_sid); 832*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryUserGroups)); 833*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 834*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 835*11337SWilliam.Krier@Sun.COM } 836*11337SWilliam.Krier@Sun.COM 837*11337SWilliam.Krier@Sun.COM /* 838*11337SWilliam.Krier@Sun.COM * samr_s_OpenGroup 839*11337SWilliam.Krier@Sun.COM * 840*11337SWilliam.Krier@Sun.COM * This is a request to open a group within the specified domain in the 841*11337SWilliam.Krier@Sun.COM * local SAM database. The caller must supply a valid domain handle, 842*11337SWilliam.Krier@Sun.COM * obtained via a successful domain open request. The group is 843*11337SWilliam.Krier@Sun.COM * specified by the rid in the request. If this is a local RID it 844*11337SWilliam.Krier@Sun.COM * should already be encoded with type information. 845*11337SWilliam.Krier@Sun.COM * 846*11337SWilliam.Krier@Sun.COM * We return a handle to be used to access information about this group. 847*11337SWilliam.Krier@Sun.COM */ 848*11337SWilliam.Krier@Sun.COM static int 849*11337SWilliam.Krier@Sun.COM samr_s_OpenGroup(void *arg, ndr_xa_t *mxa) 850*11337SWilliam.Krier@Sun.COM { 851*11337SWilliam.Krier@Sun.COM struct samr_OpenGroup *param = arg; 852*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle; 853*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 854*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 855*11337SWilliam.Krier@Sun.COM 856*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 857*11337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 858*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 859*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 860*11337SWilliam.Krier@Sun.COM } 861*11337SWilliam.Krier@Sun.COM 862*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 863*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid); 864*11337SWilliam.Krier@Sun.COM 865*11337SWilliam.Krier@Sun.COM if (id) { 866*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->group_handle, sizeof (samr_handle_t)); 867*11337SWilliam.Krier@Sun.COM param->status = 0; 868*11337SWilliam.Krier@Sun.COM } else { 869*11337SWilliam.Krier@Sun.COM bzero(¶m->group_handle, sizeof (samr_handle_t)); 870*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 871*11337SWilliam.Krier@Sun.COM } 872*11337SWilliam.Krier@Sun.COM 873*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 874*11337SWilliam.Krier@Sun.COM } 875*11337SWilliam.Krier@Sun.COM 876*11337SWilliam.Krier@Sun.COM /* 877*11337SWilliam.Krier@Sun.COM * samr_s_Connect 878*11337SWilliam.Krier@Sun.COM * 879*11337SWilliam.Krier@Sun.COM * This is a request to connect to the local SAM database. 880*11337SWilliam.Krier@Sun.COM * We don't support any form of update request and our database doesn't 881*11337SWilliam.Krier@Sun.COM * contain any private information, so there is little point in doing 882*11337SWilliam.Krier@Sun.COM * any access access checking here. 883*11337SWilliam.Krier@Sun.COM * 884*11337SWilliam.Krier@Sun.COM * Return a handle for use with subsequent SAM requests. 885*11337SWilliam.Krier@Sun.COM */ 886*11337SWilliam.Krier@Sun.COM static int 887*11337SWilliam.Krier@Sun.COM samr_s_Connect(void *arg, ndr_xa_t *mxa) 888*11337SWilliam.Krier@Sun.COM { 889*11337SWilliam.Krier@Sun.COM struct samr_Connect *param = arg; 890*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id; 891*11337SWilliam.Krier@Sun.COM 892*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0); 893*11337SWilliam.Krier@Sun.COM if (id) { 894*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->handle, sizeof (samr_handle_t)); 895*11337SWilliam.Krier@Sun.COM param->status = 0; 896*11337SWilliam.Krier@Sun.COM } else { 897*11337SWilliam.Krier@Sun.COM bzero(¶m->handle, sizeof (samr_handle_t)); 898*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 899*11337SWilliam.Krier@Sun.COM } 900*11337SWilliam.Krier@Sun.COM 901*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 902*11337SWilliam.Krier@Sun.COM } 903*11337SWilliam.Krier@Sun.COM 904*11337SWilliam.Krier@Sun.COM /* 905*11337SWilliam.Krier@Sun.COM * samr_s_GetUserPwInfo 906*11337SWilliam.Krier@Sun.COM * 907*11337SWilliam.Krier@Sun.COM * This is a request to get a user's password. 908*11337SWilliam.Krier@Sun.COM */ 909*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 910*11337SWilliam.Krier@Sun.COM static int 911*11337SWilliam.Krier@Sun.COM samr_s_GetUserPwInfo(void *arg, ndr_xa_t *mxa) 912*11337SWilliam.Krier@Sun.COM { 913*11337SWilliam.Krier@Sun.COM struct samr_GetUserPwInfo *param = arg; 914*11337SWilliam.Krier@Sun.COM 915*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_GetUserPwInfo)); 916*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 917*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 918*11337SWilliam.Krier@Sun.COM } 919*11337SWilliam.Krier@Sun.COM 920*11337SWilliam.Krier@Sun.COM /* 921*11337SWilliam.Krier@Sun.COM * samr_s_CreateUser 922*11337SWilliam.Krier@Sun.COM */ 923*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 924*11337SWilliam.Krier@Sun.COM static int 925*11337SWilliam.Krier@Sun.COM samr_s_CreateUser(void *arg, ndr_xa_t *mxa) 926*11337SWilliam.Krier@Sun.COM { 927*11337SWilliam.Krier@Sun.COM struct samr_CreateUser *param = arg; 928*11337SWilliam.Krier@Sun.COM 929*11337SWilliam.Krier@Sun.COM bzero(¶m->user_handle, sizeof (samr_handle_t)); 930*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 931*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 932*11337SWilliam.Krier@Sun.COM } 933*11337SWilliam.Krier@Sun.COM 934*11337SWilliam.Krier@Sun.COM /* 935*11337SWilliam.Krier@Sun.COM * samr_s_ChangeUserPasswd 936*11337SWilliam.Krier@Sun.COM */ 937*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 938*11337SWilliam.Krier@Sun.COM static int 939*11337SWilliam.Krier@Sun.COM samr_s_ChangeUserPasswd(void *arg, ndr_xa_t *mxa) 940*11337SWilliam.Krier@Sun.COM { 941*11337SWilliam.Krier@Sun.COM struct samr_ChangeUserPasswd *param = arg; 942*11337SWilliam.Krier@Sun.COM 943*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_ChangeUserPasswd)); 944*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 945*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 946*11337SWilliam.Krier@Sun.COM } 947*11337SWilliam.Krier@Sun.COM 948*11337SWilliam.Krier@Sun.COM /* 949*11337SWilliam.Krier@Sun.COM * samr_s_GetDomainPwInfo 950*11337SWilliam.Krier@Sun.COM */ 951*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 952*11337SWilliam.Krier@Sun.COM static int 953*11337SWilliam.Krier@Sun.COM samr_s_GetDomainPwInfo(void *arg, ndr_xa_t *mxa) 954*11337SWilliam.Krier@Sun.COM { 955*11337SWilliam.Krier@Sun.COM struct samr_GetDomainPwInfo *param = arg; 956*11337SWilliam.Krier@Sun.COM 957*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_GetDomainPwInfo)); 958*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 959*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 960*11337SWilliam.Krier@Sun.COM } 961*11337SWilliam.Krier@Sun.COM 962*11337SWilliam.Krier@Sun.COM /* 963*11337SWilliam.Krier@Sun.COM * samr_s_SetUserInfo 964*11337SWilliam.Krier@Sun.COM */ 965*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 966*11337SWilliam.Krier@Sun.COM static int 967*11337SWilliam.Krier@Sun.COM samr_s_SetUserInfo(void *arg, ndr_xa_t *mxa) 968*11337SWilliam.Krier@Sun.COM { 969*11337SWilliam.Krier@Sun.COM struct samr_SetUserInfo *param = arg; 970*11337SWilliam.Krier@Sun.COM 971*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_SetUserInfo)); 972*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 973*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 974*11337SWilliam.Krier@Sun.COM } 975*11337SWilliam.Krier@Sun.COM 976*11337SWilliam.Krier@Sun.COM /* 977*11337SWilliam.Krier@Sun.COM * samr_s_QueryDispInfo 978*11337SWilliam.Krier@Sun.COM * 979*11337SWilliam.Krier@Sun.COM * This function currently return local users' information only. 980*11337SWilliam.Krier@Sun.COM * This RPC is called repeatedly until all the users info are 981*11337SWilliam.Krier@Sun.COM * retrieved. 982*11337SWilliam.Krier@Sun.COM * 983*11337SWilliam.Krier@Sun.COM * The total count and the returned count are returned as total size 984*11337SWilliam.Krier@Sun.COM * and returned size. The client doesn't seem to care. 985*11337SWilliam.Krier@Sun.COM */ 986*11337SWilliam.Krier@Sun.COM static int 987*11337SWilliam.Krier@Sun.COM samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa) 988*11337SWilliam.Krier@Sun.COM { 989*11337SWilliam.Krier@Sun.COM struct samr_QueryDispInfo *param = arg; 990*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 991*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 992*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 993*11337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 994*11337SWilliam.Krier@Sun.COM struct user_acct_info *user; 995*11337SWilliam.Krier@Sun.COM smb_pwditer_t pwi; 996*11337SWilliam.Krier@Sun.COM smb_luser_t *uinfo; 997*11337SWilliam.Krier@Sun.COM int num_users; 998*11337SWilliam.Krier@Sun.COM int start_idx; 999*11337SWilliam.Krier@Sun.COM int max_retcnt, retcnt; 1000*11337SWilliam.Krier@Sun.COM int skip; 1001*11337SWilliam.Krier@Sun.COM 1002*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1003*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 1004*11337SWilliam.Krier@Sun.COM goto error; 1005*11337SWilliam.Krier@Sun.COM } 1006*11337SWilliam.Krier@Sun.COM 1007*11337SWilliam.Krier@Sun.COM if (!SAMR_VALID_DISPLEVEL(param->level)) { 1008*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 1009*11337SWilliam.Krier@Sun.COM goto error; 1010*11337SWilliam.Krier@Sun.COM } 1011*11337SWilliam.Krier@Sun.COM 1012*11337SWilliam.Krier@Sun.COM if (!SAMR_SUPPORTED_DISPLEVEL(param->level)) { 1013*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NOT_IMPLEMENTED; 1014*11337SWilliam.Krier@Sun.COM goto error; 1015*11337SWilliam.Krier@Sun.COM } 1016*11337SWilliam.Krier@Sun.COM 1017*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1018*11337SWilliam.Krier@Sun.COM 1019*11337SWilliam.Krier@Sun.COM switch (data->kd_type) { 1020*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_BUILTIN: 1021*11337SWilliam.Krier@Sun.COM goto no_info; 1022*11337SWilliam.Krier@Sun.COM 1023*11337SWilliam.Krier@Sun.COM case SMB_DOMAIN_LOCAL: 1024*11337SWilliam.Krier@Sun.COM num_users = smb_sam_usr_cnt(); 1025*11337SWilliam.Krier@Sun.COM start_idx = param->start_idx; 1026*11337SWilliam.Krier@Sun.COM if ((num_users == 0) || (start_idx >= num_users)) 1027*11337SWilliam.Krier@Sun.COM goto no_info; 1028*11337SWilliam.Krier@Sun.COM 1029*11337SWilliam.Krier@Sun.COM max_retcnt = num_users - start_idx; 1030*11337SWilliam.Krier@Sun.COM if (max_retcnt > param->max_entries) 1031*11337SWilliam.Krier@Sun.COM max_retcnt = param->max_entries; 1032*11337SWilliam.Krier@Sun.COM param->users.acct = NDR_MALLOC(mxa, 1033*11337SWilliam.Krier@Sun.COM max_retcnt * sizeof (struct user_acct_info)); 1034*11337SWilliam.Krier@Sun.COM user = param->users.acct; 1035*11337SWilliam.Krier@Sun.COM if (user == NULL) { 1036*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 1037*11337SWilliam.Krier@Sun.COM goto error; 1038*11337SWilliam.Krier@Sun.COM } 1039*11337SWilliam.Krier@Sun.COM bzero(user, max_retcnt * sizeof (struct user_acct_info)); 1040*11337SWilliam.Krier@Sun.COM 1041*11337SWilliam.Krier@Sun.COM if (smb_pwd_iteropen(&pwi) != SMB_PWE_SUCCESS) 1042*11337SWilliam.Krier@Sun.COM goto no_info; 1043*11337SWilliam.Krier@Sun.COM 1044*11337SWilliam.Krier@Sun.COM skip = retcnt = 0; 1045*11337SWilliam.Krier@Sun.COM while ((uinfo = smb_pwd_iterate(&pwi)) != NULL) { 1046*11337SWilliam.Krier@Sun.COM if (skip++ < start_idx) 1047*11337SWilliam.Krier@Sun.COM continue; 1048*11337SWilliam.Krier@Sun.COM 1049*11337SWilliam.Krier@Sun.COM if (retcnt++ >= max_retcnt) 1050*11337SWilliam.Krier@Sun.COM break; 1051*11337SWilliam.Krier@Sun.COM 1052*11337SWilliam.Krier@Sun.COM assert(uinfo->su_name != NULL); 1053*11337SWilliam.Krier@Sun.COM 1054*11337SWilliam.Krier@Sun.COM user->index = start_idx + retcnt; 1055*11337SWilliam.Krier@Sun.COM user->rid = uinfo->su_rid; 1056*11337SWilliam.Krier@Sun.COM user->ctrl = ACF_NORMUSER | ACF_PWDNOEXP; 1057*11337SWilliam.Krier@Sun.COM if (uinfo->su_ctrl & SMB_PWF_DISABLE) 1058*11337SWilliam.Krier@Sun.COM user->ctrl |= ACF_DISABLED; 1059*11337SWilliam.Krier@Sun.COM if (NDR_MSTRING(mxa, uinfo->su_name, 1060*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->name) == -1) { 1061*11337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 1062*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 1063*11337SWilliam.Krier@Sun.COM goto error; 1064*11337SWilliam.Krier@Sun.COM } 1065*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_fullname, 1066*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->fullname); 1067*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, uinfo->su_desc, 1068*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&user->desc); 1069*11337SWilliam.Krier@Sun.COM user++; 1070*11337SWilliam.Krier@Sun.COM } 1071*11337SWilliam.Krier@Sun.COM smb_pwd_iterclose(&pwi); 1072*11337SWilliam.Krier@Sun.COM 1073*11337SWilliam.Krier@Sun.COM if (retcnt >= max_retcnt) { 1074*11337SWilliam.Krier@Sun.COM retcnt = max_retcnt; 1075*11337SWilliam.Krier@Sun.COM param->status = status; 1076*11337SWilliam.Krier@Sun.COM } else { 1077*11337SWilliam.Krier@Sun.COM param->status = ERROR_MORE_ENTRIES; 1078*11337SWilliam.Krier@Sun.COM } 1079*11337SWilliam.Krier@Sun.COM 1080*11337SWilliam.Krier@Sun.COM param->users.total_size = num_users; 1081*11337SWilliam.Krier@Sun.COM param->users.returned_size = retcnt; 1082*11337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 1083*11337SWilliam.Krier@Sun.COM param->users.count = retcnt; 1084*11337SWilliam.Krier@Sun.COM 1085*11337SWilliam.Krier@Sun.COM break; 1086*11337SWilliam.Krier@Sun.COM 1087*11337SWilliam.Krier@Sun.COM default: 1088*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 1089*11337SWilliam.Krier@Sun.COM goto error; 1090*11337SWilliam.Krier@Sun.COM } 1091*11337SWilliam.Krier@Sun.COM 1092*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1093*11337SWilliam.Krier@Sun.COM 1094*11337SWilliam.Krier@Sun.COM no_info: 1095*11337SWilliam.Krier@Sun.COM param->users.total_size = 0; 1096*11337SWilliam.Krier@Sun.COM param->users.returned_size = 0; 1097*11337SWilliam.Krier@Sun.COM param->users.switch_value = param->level; 1098*11337SWilliam.Krier@Sun.COM param->users.count = 0; 1099*11337SWilliam.Krier@Sun.COM param->users.acct = NULL; 1100*11337SWilliam.Krier@Sun.COM param->status = status; 1101*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1102*11337SWilliam.Krier@Sun.COM 1103*11337SWilliam.Krier@Sun.COM error: 1104*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_QueryDispInfo)); 1105*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 1106*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1107*11337SWilliam.Krier@Sun.COM } 1108*11337SWilliam.Krier@Sun.COM 1109*11337SWilliam.Krier@Sun.COM /* 1110*11337SWilliam.Krier@Sun.COM * samr_s_EnumDomainGroups 1111*11337SWilliam.Krier@Sun.COM * 1112*11337SWilliam.Krier@Sun.COM * 1113*11337SWilliam.Krier@Sun.COM * This function is supposed to return local group information. 1114*11337SWilliam.Krier@Sun.COM * As we don't support local users, this function dosen't send 1115*11337SWilliam.Krier@Sun.COM * back any information. 1116*11337SWilliam.Krier@Sun.COM * 1117*11337SWilliam.Krier@Sun.COM * Added template that returns information for a domain group as None. 1118*11337SWilliam.Krier@Sun.COM * All information is hard-coded from packet captures. 1119*11337SWilliam.Krier@Sun.COM */ 1120*11337SWilliam.Krier@Sun.COM static int 1121*11337SWilliam.Krier@Sun.COM samr_s_EnumDomainGroups(void *arg, ndr_xa_t *mxa) 1122*11337SWilliam.Krier@Sun.COM { 1123*11337SWilliam.Krier@Sun.COM struct samr_EnumDomainGroups *param = arg; 1124*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1125*11337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 1126*11337SWilliam.Krier@Sun.COM 1127*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) 1128*11337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1129*11337SWilliam.Krier@Sun.COM 1130*11337SWilliam.Krier@Sun.COM param->total_size = 0; 1131*11337SWilliam.Krier@Sun.COM param->returned_size = 0; 1132*11337SWilliam.Krier@Sun.COM param->switch_value = 3; 1133*11337SWilliam.Krier@Sun.COM param->count = 0; 1134*11337SWilliam.Krier@Sun.COM param->groups = 0; 1135*11337SWilliam.Krier@Sun.COM param->status = status; 1136*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1137*11337SWilliam.Krier@Sun.COM 1138*11337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_GROUPS 1139*11337SWilliam.Krier@Sun.COM if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) { 1140*11337SWilliam.Krier@Sun.COM param->total_size = 0; 1141*11337SWilliam.Krier@Sun.COM param->returned_size = 0; 1142*11337SWilliam.Krier@Sun.COM param->switch_value = 3; 1143*11337SWilliam.Krier@Sun.COM param->count = 0; 1144*11337SWilliam.Krier@Sun.COM param->groups = 0; 1145*11337SWilliam.Krier@Sun.COM } else { 1146*11337SWilliam.Krier@Sun.COM param->total_size = 64; 1147*11337SWilliam.Krier@Sun.COM param->returned_size = 64; 1148*11337SWilliam.Krier@Sun.COM param->switch_value = 3; 1149*11337SWilliam.Krier@Sun.COM param->count = 1; 1150*11337SWilliam.Krier@Sun.COM param->groups = (struct group_disp_info *)NDR_MALLOC( 1151*11337SWilliam.Krier@Sun.COM mxa, sizeof (struct group_disp_info)); 1152*11337SWilliam.Krier@Sun.COM 1153*11337SWilliam.Krier@Sun.COM param->groups->count = 1; 1154*11337SWilliam.Krier@Sun.COM param->groups->acct[0].index = 1; 1155*11337SWilliam.Krier@Sun.COM param->groups->acct[0].rid = 513; 1156*11337SWilliam.Krier@Sun.COM param->groups->acct[0].ctrl = 0x7; 1157*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "None", 1158*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].name); 1159*11337SWilliam.Krier@Sun.COM 1160*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, "Ordinary users", 1161*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->groups->acct[0].desc); 1162*11337SWilliam.Krier@Sun.COM } 1163*11337SWilliam.Krier@Sun.COM 1164*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 1165*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1166*11337SWilliam.Krier@Sun.COM #endif 1167*11337SWilliam.Krier@Sun.COM } 1168*11337SWilliam.Krier@Sun.COM 1169*11337SWilliam.Krier@Sun.COM /* 1170*11337SWilliam.Krier@Sun.COM * samr_s_OpenAlias 1171*11337SWilliam.Krier@Sun.COM * 1172*11337SWilliam.Krier@Sun.COM * Lookup for requested alias, if it exists return a handle 1173*11337SWilliam.Krier@Sun.COM * for that alias. The alias domain sid should match with 1174*11337SWilliam.Krier@Sun.COM * the passed domain handle. 1175*11337SWilliam.Krier@Sun.COM */ 1176*11337SWilliam.Krier@Sun.COM static int 1177*11337SWilliam.Krier@Sun.COM samr_s_OpenAlias(void *arg, ndr_xa_t *mxa) 1178*11337SWilliam.Krier@Sun.COM { 1179*11337SWilliam.Krier@Sun.COM struct samr_OpenAlias *param = arg; 1180*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1181*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 1182*11337SWilliam.Krier@Sun.COM uint32_t status; 1183*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 1184*11337SWilliam.Krier@Sun.COM int rc; 1185*11337SWilliam.Krier@Sun.COM 1186*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1187*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 1188*11337SWilliam.Krier@Sun.COM goto open_alias_err; 1189*11337SWilliam.Krier@Sun.COM } 1190*11337SWilliam.Krier@Sun.COM 1191*11337SWilliam.Krier@Sun.COM if (param->access_mask != SAMR_ALIAS_ACCESS_GET_INFO) { 1192*11337SWilliam.Krier@Sun.COM status = NT_STATUS_ACCESS_DENIED; 1193*11337SWilliam.Krier@Sun.COM goto open_alias_err; 1194*11337SWilliam.Krier@Sun.COM } 1195*11337SWilliam.Krier@Sun.COM 1196*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1197*11337SWilliam.Krier@Sun.COM rc = smb_lgrp_getbyrid(param->rid, (smb_gdomain_t)data->kd_type, NULL); 1198*11337SWilliam.Krier@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1199*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1200*11337SWilliam.Krier@Sun.COM goto open_alias_err; 1201*11337SWilliam.Krier@Sun.COM } 1202*11337SWilliam.Krier@Sun.COM 1203*11337SWilliam.Krier@Sun.COM id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid); 1204*11337SWilliam.Krier@Sun.COM if (id) { 1205*11337SWilliam.Krier@Sun.COM bcopy(id, ¶m->alias_handle, sizeof (samr_handle_t)); 1206*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 1207*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1208*11337SWilliam.Krier@Sun.COM } 1209*11337SWilliam.Krier@Sun.COM 1210*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 1211*11337SWilliam.Krier@Sun.COM 1212*11337SWilliam.Krier@Sun.COM open_alias_err: 1213*11337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1214*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 1215*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1216*11337SWilliam.Krier@Sun.COM } 1217*11337SWilliam.Krier@Sun.COM 1218*11337SWilliam.Krier@Sun.COM /* 1219*11337SWilliam.Krier@Sun.COM * samr_s_CreateDomainAlias 1220*11337SWilliam.Krier@Sun.COM * 1221*11337SWilliam.Krier@Sun.COM * Creates a local group in the security database, which is the 1222*11337SWilliam.Krier@Sun.COM * security accounts manager (SAM) 1223*11337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupAdd. 1224*11337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 1225*11337SWilliam.Krier@Sun.COM * The peice of code that creates a local group doesn't get compiled. 1226*11337SWilliam.Krier@Sun.COM */ 1227*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 1228*11337SWilliam.Krier@Sun.COM static int 1229*11337SWilliam.Krier@Sun.COM samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa) 1230*11337SWilliam.Krier@Sun.COM { 1231*11337SWilliam.Krier@Sun.COM struct samr_CreateDomainAlias *param = arg; 1232*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1233*11337SWilliam.Krier@Sun.COM 1234*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) { 1235*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 1236*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1237*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1238*11337SWilliam.Krier@Sun.COM } 1239*11337SWilliam.Krier@Sun.COM 1240*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_CreateDomainAlias)); 1241*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1242*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1243*11337SWilliam.Krier@Sun.COM 1244*11337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_ADD_ALIAS 1245*11337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 1246*11337SWilliam.Krier@Sun.COM nt_group_t *grp; 1247*11337SWilliam.Krier@Sun.COM char *alias_name; 1248*11337SWilliam.Krier@Sun.COM 1249*11337SWilliam.Krier@Sun.COM alias_name = param->alias_name.str; 1250*11337SWilliam.Krier@Sun.COM if (alias_name == 0) { 1251*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER; 1252*11337SWilliam.Krier@Sun.COM goto create_alias_err; 1253*11337SWilliam.Krier@Sun.COM } 1254*11337SWilliam.Krier@Sun.COM 1255*11337SWilliam.Krier@Sun.COM /* 1256*11337SWilliam.Krier@Sun.COM * Check access mask. User should be member of 1257*11337SWilliam.Krier@Sun.COM * Administrators or Account Operators local group. 1258*11337SWilliam.Krier@Sun.COM */ 1259*11337SWilliam.Krier@Sun.COM status = nt_group_add(alias_name, 0, 1260*11337SWilliam.Krier@Sun.COM NT_GROUP_AF_ADD | NT_GROUP_AF_LOCAL); 1261*11337SWilliam.Krier@Sun.COM 1262*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 1263*11337SWilliam.Krier@Sun.COM goto create_alias_err; 1264*11337SWilliam.Krier@Sun.COM 1265*11337SWilliam.Krier@Sun.COM grp = nt_group_getinfo(alias_name, RWLOCK_READER); 1266*11337SWilliam.Krier@Sun.COM if (grp == NULL) { 1267*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INTERNAL_ERROR; 1268*11337SWilliam.Krier@Sun.COM goto create_alias_err; 1269*11337SWilliam.Krier@Sun.COM } 1270*11337SWilliam.Krier@Sun.COM 1271*11337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(grp->sid, ¶m->rid); 1272*11337SWilliam.Krier@Sun.COM nt_group_putinfo(grp); 1273*11337SWilliam.Krier@Sun.COM handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY, 1274*11337SWilliam.Krier@Sun.COM param->rid); 1275*11337SWilliam.Krier@Sun.COM bcopy(handle, ¶m->alias_handle, sizeof (samr_handle_t)); 1276*11337SWilliam.Krier@Sun.COM 1277*11337SWilliam.Krier@Sun.COM param->status = 0; 1278*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1279*11337SWilliam.Krier@Sun.COM 1280*11337SWilliam.Krier@Sun.COM create_alias_err: 1281*11337SWilliam.Krier@Sun.COM bzero(¶m->alias_handle, sizeof (samr_handle_t)); 1282*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 1283*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1284*11337SWilliam.Krier@Sun.COM #endif 1285*11337SWilliam.Krier@Sun.COM } 1286*11337SWilliam.Krier@Sun.COM 1287*11337SWilliam.Krier@Sun.COM /* 1288*11337SWilliam.Krier@Sun.COM * samr_s_SetAliasInfo 1289*11337SWilliam.Krier@Sun.COM * 1290*11337SWilliam.Krier@Sun.COM * Similar to NetLocalGroupSetInfo. 1291*11337SWilliam.Krier@Sun.COM */ 1292*11337SWilliam.Krier@Sun.COM static int 1293*11337SWilliam.Krier@Sun.COM samr_s_SetAliasInfo(void *arg, ndr_xa_t *mxa) 1294*11337SWilliam.Krier@Sun.COM { 1295*11337SWilliam.Krier@Sun.COM struct samr_SetAliasInfo *param = arg; 1296*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1297*11337SWilliam.Krier@Sun.COM DWORD status = NT_STATUS_SUCCESS; 1298*11337SWilliam.Krier@Sun.COM 1299*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) 1300*11337SWilliam.Krier@Sun.COM status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1301*11337SWilliam.Krier@Sun.COM 1302*11337SWilliam.Krier@Sun.COM param->status = status; 1303*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1304*11337SWilliam.Krier@Sun.COM } 1305*11337SWilliam.Krier@Sun.COM 1306*11337SWilliam.Krier@Sun.COM /* 1307*11337SWilliam.Krier@Sun.COM * samr_s_QueryAliasInfo 1308*11337SWilliam.Krier@Sun.COM * 1309*11337SWilliam.Krier@Sun.COM * Retrieves information about the specified local group account 1310*11337SWilliam.Krier@Sun.COM * by given handle. 1311*11337SWilliam.Krier@Sun.COM */ 1312*11337SWilliam.Krier@Sun.COM static int 1313*11337SWilliam.Krier@Sun.COM samr_s_QueryAliasInfo(void *arg, ndr_xa_t *mxa) 1314*11337SWilliam.Krier@Sun.COM { 1315*11337SWilliam.Krier@Sun.COM struct samr_QueryAliasInfo *param = arg; 1316*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1317*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 1318*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 1319*11337SWilliam.Krier@Sun.COM smb_group_t grp; 1320*11337SWilliam.Krier@Sun.COM uint32_t status; 1321*11337SWilliam.Krier@Sun.COM int rc; 1322*11337SWilliam.Krier@Sun.COM 1323*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) { 1324*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_HANDLE; 1325*11337SWilliam.Krier@Sun.COM goto query_alias_err; 1326*11337SWilliam.Krier@Sun.COM } 1327*11337SWilliam.Krier@Sun.COM 1328*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1329*11337SWilliam.Krier@Sun.COM rc = smb_lgrp_getbyrid(data->kd_rid, (smb_gdomain_t)data->kd_type, 1330*11337SWilliam.Krier@Sun.COM &grp); 1331*11337SWilliam.Krier@Sun.COM if (rc != SMB_LGRP_SUCCESS) { 1332*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1333*11337SWilliam.Krier@Sun.COM goto query_alias_err; 1334*11337SWilliam.Krier@Sun.COM } 1335*11337SWilliam.Krier@Sun.COM 1336*11337SWilliam.Krier@Sun.COM switch (param->level) { 1337*11337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_1: 1338*11337SWilliam.Krier@Sun.COM param->ru.info1.level = param->level; 1339*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 1340*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.name); 1341*11337SWilliam.Krier@Sun.COM 1342*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_cmnt, 1343*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info1.desc); 1344*11337SWilliam.Krier@Sun.COM 1345*11337SWilliam.Krier@Sun.COM param->ru.info1.unknown = 1; 1346*11337SWilliam.Krier@Sun.COM break; 1347*11337SWilliam.Krier@Sun.COM 1348*11337SWilliam.Krier@Sun.COM case SAMR_QUERY_ALIAS_INFO_3: 1349*11337SWilliam.Krier@Sun.COM param->ru.info3.level = param->level; 1350*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_cmnt, 1351*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)¶m->ru.info3.desc); 1352*11337SWilliam.Krier@Sun.COM break; 1353*11337SWilliam.Krier@Sun.COM 1354*11337SWilliam.Krier@Sun.COM default: 1355*11337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 1356*11337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS; 1357*11337SWilliam.Krier@Sun.COM goto query_alias_err; 1358*11337SWilliam.Krier@Sun.COM }; 1359*11337SWilliam.Krier@Sun.COM 1360*11337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 1361*11337SWilliam.Krier@Sun.COM param->address = (DWORD)(uintptr_t)¶m->ru; 1362*11337SWilliam.Krier@Sun.COM param->status = 0; 1363*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1364*11337SWilliam.Krier@Sun.COM 1365*11337SWilliam.Krier@Sun.COM query_alias_err: 1366*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 1367*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1368*11337SWilliam.Krier@Sun.COM } 1369*11337SWilliam.Krier@Sun.COM 1370*11337SWilliam.Krier@Sun.COM /* 1371*11337SWilliam.Krier@Sun.COM * samr_s_DeleteDomainAlias 1372*11337SWilliam.Krier@Sun.COM * 1373*11337SWilliam.Krier@Sun.COM * Deletes a local group account and all its members from the 1374*11337SWilliam.Krier@Sun.COM * security database, which is the security accounts manager (SAM) database. 1375*11337SWilliam.Krier@Sun.COM * Only members of the Administrators or Account Operators local group can 1376*11337SWilliam.Krier@Sun.COM * execute this function. 1377*11337SWilliam.Krier@Sun.COM * For more information you can look at MSDN page for NetLocalGroupSetInfo. 1378*11337SWilliam.Krier@Sun.COM * 1379*11337SWilliam.Krier@Sun.COM * This RPC is used by CMC and right now it returns access denied. 1380*11337SWilliam.Krier@Sun.COM * The peice of code that removes a local group doesn't get compiled. 1381*11337SWilliam.Krier@Sun.COM */ 1382*11337SWilliam.Krier@Sun.COM static int 1383*11337SWilliam.Krier@Sun.COM samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa) 1384*11337SWilliam.Krier@Sun.COM { 1385*11337SWilliam.Krier@Sun.COM struct samr_DeleteDomainAlias *param = arg; 1386*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->alias_handle; 1387*11337SWilliam.Krier@Sun.COM 1388*11337SWilliam.Krier@Sun.COM if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) { 1389*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1390*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1391*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1392*11337SWilliam.Krier@Sun.COM } 1393*11337SWilliam.Krier@Sun.COM 1394*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_DeleteDomainAlias)); 1395*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED); 1396*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1397*11337SWilliam.Krier@Sun.COM 1398*11337SWilliam.Krier@Sun.COM #ifdef SAMR_SUPPORT_DEL_ALIAS 1399*11337SWilliam.Krier@Sun.COM nt_group_t *grp; 1400*11337SWilliam.Krier@Sun.COM char *alias_name; 1401*11337SWilliam.Krier@Sun.COM DWORD status; 1402*11337SWilliam.Krier@Sun.COM 1403*11337SWilliam.Krier@Sun.COM grp = nt_groups_lookup_rid(desc->discrim); 1404*11337SWilliam.Krier@Sun.COM if (grp == 0) { 1405*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_SUCH_ALIAS; 1406*11337SWilliam.Krier@Sun.COM goto delete_alias_err; 1407*11337SWilliam.Krier@Sun.COM } 1408*11337SWilliam.Krier@Sun.COM 1409*11337SWilliam.Krier@Sun.COM alias_name = strdup(grp->name); 1410*11337SWilliam.Krier@Sun.COM if (alias_name == 0) { 1411*11337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY; 1412*11337SWilliam.Krier@Sun.COM goto delete_alias_err; 1413*11337SWilliam.Krier@Sun.COM } 1414*11337SWilliam.Krier@Sun.COM 1415*11337SWilliam.Krier@Sun.COM status = nt_group_delete(alias_name); 1416*11337SWilliam.Krier@Sun.COM free(alias_name); 1417*11337SWilliam.Krier@Sun.COM if (status != NT_STATUS_SUCCESS) 1418*11337SWilliam.Krier@Sun.COM goto delete_alias_err; 1419*11337SWilliam.Krier@Sun.COM 1420*11337SWilliam.Krier@Sun.COM param->status = 0; 1421*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1422*11337SWilliam.Krier@Sun.COM 1423*11337SWilliam.Krier@Sun.COM delete_alias_err: 1424*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(status); 1425*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1426*11337SWilliam.Krier@Sun.COM #endif 1427*11337SWilliam.Krier@Sun.COM } 1428*11337SWilliam.Krier@Sun.COM 1429*11337SWilliam.Krier@Sun.COM /* 1430*11337SWilliam.Krier@Sun.COM * samr_s_EnumDomainAliases 1431*11337SWilliam.Krier@Sun.COM * 1432*11337SWilliam.Krier@Sun.COM * This function sends back a list which contains all local groups' name. 1433*11337SWilliam.Krier@Sun.COM */ 1434*11337SWilliam.Krier@Sun.COM static int 1435*11337SWilliam.Krier@Sun.COM samr_s_EnumDomainAliases(void *arg, ndr_xa_t *mxa) 1436*11337SWilliam.Krier@Sun.COM { 1437*11337SWilliam.Krier@Sun.COM struct samr_EnumDomainAliases *param = arg; 1438*11337SWilliam.Krier@Sun.COM ndr_hdid_t *id = (ndr_hdid_t *)¶m->domain_handle; 1439*11337SWilliam.Krier@Sun.COM ndr_handle_t *hd; 1440*11337SWilliam.Krier@Sun.COM samr_keydata_t *data; 1441*11337SWilliam.Krier@Sun.COM smb_group_t grp; 1442*11337SWilliam.Krier@Sun.COM smb_giter_t gi; 1443*11337SWilliam.Krier@Sun.COM int cnt, skip, i; 1444*11337SWilliam.Krier@Sun.COM struct name_rid *info; 1445*11337SWilliam.Krier@Sun.COM 1446*11337SWilliam.Krier@Sun.COM if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) { 1447*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 1448*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE); 1449*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1450*11337SWilliam.Krier@Sun.COM } 1451*11337SWilliam.Krier@Sun.COM 1452*11337SWilliam.Krier@Sun.COM data = (samr_keydata_t *)hd->nh_data; 1453*11337SWilliam.Krier@Sun.COM 1454*11337SWilliam.Krier@Sun.COM cnt = smb_sam_grp_cnt(data->kd_type); 1455*11337SWilliam.Krier@Sun.COM if (cnt <= param->resume_handle) { 1456*11337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 1457*11337SWilliam.Krier@Sun.COM sizeof (struct aliases_info)); 1458*11337SWilliam.Krier@Sun.COM 1459*11337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 1460*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 1461*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1462*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1463*11337SWilliam.Krier@Sun.COM } 1464*11337SWilliam.Krier@Sun.COM 1465*11337SWilliam.Krier@Sun.COM bzero(param->aliases, sizeof (struct aliases_info)); 1466*11337SWilliam.Krier@Sun.COM param->out_resume = 0; 1467*11337SWilliam.Krier@Sun.COM param->entries = 0; 1468*11337SWilliam.Krier@Sun.COM param->status = NT_STATUS_SUCCESS; 1469*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1470*11337SWilliam.Krier@Sun.COM } 1471*11337SWilliam.Krier@Sun.COM 1472*11337SWilliam.Krier@Sun.COM cnt -= param->resume_handle; 1473*11337SWilliam.Krier@Sun.COM param->aliases = (struct aliases_info *)NDR_MALLOC(mxa, 1474*11337SWilliam.Krier@Sun.COM sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid)); 1475*11337SWilliam.Krier@Sun.COM 1476*11337SWilliam.Krier@Sun.COM if (param->aliases == NULL) { 1477*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 1478*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY); 1479*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1480*11337SWilliam.Krier@Sun.COM } 1481*11337SWilliam.Krier@Sun.COM 1482*11337SWilliam.Krier@Sun.COM if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) { 1483*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_EnumDomainAliases)); 1484*11337SWilliam.Krier@Sun.COM param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR); 1485*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1486*11337SWilliam.Krier@Sun.COM } 1487*11337SWilliam.Krier@Sun.COM 1488*11337SWilliam.Krier@Sun.COM skip = i = 0; 1489*11337SWilliam.Krier@Sun.COM info = param->aliases->info; 1490*11337SWilliam.Krier@Sun.COM while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) { 1491*11337SWilliam.Krier@Sun.COM if ((skip++ >= param->resume_handle) && 1492*11337SWilliam.Krier@Sun.COM (grp.sg_domain == data->kd_type) && (i++ < cnt)) { 1493*11337SWilliam.Krier@Sun.COM info->rid = grp.sg_rid; 1494*11337SWilliam.Krier@Sun.COM (void) NDR_MSTRING(mxa, grp.sg_name, 1495*11337SWilliam.Krier@Sun.COM (ndr_mstring_t *)&info->name); 1496*11337SWilliam.Krier@Sun.COM 1497*11337SWilliam.Krier@Sun.COM info++; 1498*11337SWilliam.Krier@Sun.COM } 1499*11337SWilliam.Krier@Sun.COM smb_lgrp_free(&grp); 1500*11337SWilliam.Krier@Sun.COM } 1501*11337SWilliam.Krier@Sun.COM smb_lgrp_iterclose(&gi); 1502*11337SWilliam.Krier@Sun.COM 1503*11337SWilliam.Krier@Sun.COM param->aliases->count = i; 1504*11337SWilliam.Krier@Sun.COM param->aliases->address = i; 1505*11337SWilliam.Krier@Sun.COM 1506*11337SWilliam.Krier@Sun.COM param->out_resume = i; 1507*11337SWilliam.Krier@Sun.COM param->entries = i; 1508*11337SWilliam.Krier@Sun.COM param->status = 0; 1509*11337SWilliam.Krier@Sun.COM return (NDR_DRC_OK); 1510*11337SWilliam.Krier@Sun.COM } 1511*11337SWilliam.Krier@Sun.COM 1512*11337SWilliam.Krier@Sun.COM /* 1513*11337SWilliam.Krier@Sun.COM * samr_s_Connect3 1514*11337SWilliam.Krier@Sun.COM * 1515*11337SWilliam.Krier@Sun.COM * This is the connect3 form of the connect request. It contains an 1516*11337SWilliam.Krier@Sun.COM * extra parameter over samr_Connect. See samr_s_Connect for other 1517*11337SWilliam.Krier@Sun.COM * details. NT returns an RPC fault - so we can do the same for now. 1518*11337SWilliam.Krier@Sun.COM * Doing it this way should avoid the unsupported opnum error message 1519*11337SWilliam.Krier@Sun.COM * appearing in the log. 1520*11337SWilliam.Krier@Sun.COM */ 1521*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 1522*11337SWilliam.Krier@Sun.COM static int 1523*11337SWilliam.Krier@Sun.COM samr_s_Connect3(void *arg, ndr_xa_t *mxa) 1524*11337SWilliam.Krier@Sun.COM { 1525*11337SWilliam.Krier@Sun.COM struct samr_Connect3 *param = arg; 1526*11337SWilliam.Krier@Sun.COM 1527*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect3)); 1528*11337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 1529*11337SWilliam.Krier@Sun.COM } 1530*11337SWilliam.Krier@Sun.COM 1531*11337SWilliam.Krier@Sun.COM 1532*11337SWilliam.Krier@Sun.COM /* 1533*11337SWilliam.Krier@Sun.COM * samr_s_Connect4 1534*11337SWilliam.Krier@Sun.COM * 1535*11337SWilliam.Krier@Sun.COM * This is the connect4 form of the connect request used by Windows XP. 1536*11337SWilliam.Krier@Sun.COM * Returns an RPC fault for now. 1537*11337SWilliam.Krier@Sun.COM */ 1538*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 1539*11337SWilliam.Krier@Sun.COM static int 1540*11337SWilliam.Krier@Sun.COM samr_s_Connect4(void *arg, ndr_xa_t *mxa) 1541*11337SWilliam.Krier@Sun.COM { 1542*11337SWilliam.Krier@Sun.COM struct samr_Connect4 *param = arg; 1543*11337SWilliam.Krier@Sun.COM 1544*11337SWilliam.Krier@Sun.COM bzero(param, sizeof (struct samr_Connect4)); 1545*11337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_REQUEST_OPNUM_INVALID); 1546*11337SWilliam.Krier@Sun.COM } 1547*11337SWilliam.Krier@Sun.COM 1548*11337SWilliam.Krier@Sun.COM static ndr_stub_table_t samr_stub_table[] = { 1549*11337SWilliam.Krier@Sun.COM { samr_s_ConnectAnon, SAMR_OPNUM_ConnectAnon }, 1550*11337SWilliam.Krier@Sun.COM { samr_s_CloseHandle, SAMR_OPNUM_CloseHandle }, 1551*11337SWilliam.Krier@Sun.COM { samr_s_LookupDomain, SAMR_OPNUM_LookupDomain }, 1552*11337SWilliam.Krier@Sun.COM { samr_s_EnumLocalDomains, SAMR_OPNUM_EnumLocalDomains }, 1553*11337SWilliam.Krier@Sun.COM { samr_s_OpenDomain, SAMR_OPNUM_OpenDomain }, 1554*11337SWilliam.Krier@Sun.COM { samr_s_QueryDomainInfo, SAMR_OPNUM_QueryDomainInfo }, 1555*11337SWilliam.Krier@Sun.COM { samr_s_LookupNames, SAMR_OPNUM_LookupNames }, 1556*11337SWilliam.Krier@Sun.COM { samr_s_OpenUser, SAMR_OPNUM_OpenUser }, 1557*11337SWilliam.Krier@Sun.COM { samr_s_DeleteUser, SAMR_OPNUM_DeleteUser }, 1558*11337SWilliam.Krier@Sun.COM { samr_s_QueryUserInfo, SAMR_OPNUM_QueryUserInfo }, 1559*11337SWilliam.Krier@Sun.COM { samr_s_QueryUserGroups, SAMR_OPNUM_QueryUserGroups }, 1560*11337SWilliam.Krier@Sun.COM { samr_s_OpenGroup, SAMR_OPNUM_OpenGroup }, 1561*11337SWilliam.Krier@Sun.COM { samr_s_Connect, SAMR_OPNUM_Connect }, 1562*11337SWilliam.Krier@Sun.COM { samr_s_GetUserPwInfo, SAMR_OPNUM_GetUserPwInfo }, 1563*11337SWilliam.Krier@Sun.COM { samr_s_CreateUser, SAMR_OPNUM_CreateUser }, 1564*11337SWilliam.Krier@Sun.COM { samr_s_ChangeUserPasswd, SAMR_OPNUM_ChangeUserPasswd }, 1565*11337SWilliam.Krier@Sun.COM { samr_s_GetDomainPwInfo, SAMR_OPNUM_GetDomainPwInfo }, 1566*11337SWilliam.Krier@Sun.COM { samr_s_SetUserInfo, SAMR_OPNUM_SetUserInfo }, 1567*11337SWilliam.Krier@Sun.COM { samr_s_Connect3, SAMR_OPNUM_Connect3 }, 1568*11337SWilliam.Krier@Sun.COM { samr_s_Connect4, SAMR_OPNUM_Connect4 }, 1569*11337SWilliam.Krier@Sun.COM { samr_s_QueryDispInfo, SAMR_OPNUM_QueryDispInfo }, 1570*11337SWilliam.Krier@Sun.COM { samr_s_OpenAlias, SAMR_OPNUM_OpenAlias }, 1571*11337SWilliam.Krier@Sun.COM { samr_s_CreateDomainAlias, SAMR_OPNUM_CreateDomainAlias }, 1572*11337SWilliam.Krier@Sun.COM { samr_s_SetAliasInfo, SAMR_OPNUM_SetAliasInfo }, 1573*11337SWilliam.Krier@Sun.COM { samr_s_QueryAliasInfo, SAMR_OPNUM_QueryAliasInfo }, 1574*11337SWilliam.Krier@Sun.COM { samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias }, 1575*11337SWilliam.Krier@Sun.COM { samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases }, 1576*11337SWilliam.Krier@Sun.COM { samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups }, 1577*11337SWilliam.Krier@Sun.COM {0} 1578*11337SWilliam.Krier@Sun.COM }; 1579*11337SWilliam.Krier@Sun.COM 1580*11337SWilliam.Krier@Sun.COM /* 1581*11337SWilliam.Krier@Sun.COM * There is a bug in the way that midl and the marshalling code handles 1582*11337SWilliam.Krier@Sun.COM * unions so we need to fix some of the data offsets at runtime. The 1583*11337SWilliam.Krier@Sun.COM * following macros and the fixup functions handle the corrections. 1584*11337SWilliam.Krier@Sun.COM */ 1585*11337SWilliam.Krier@Sun.COM 1586*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo_ru); 1587*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfoRes); 1588*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryAliasInfo); 1589*11337SWilliam.Krier@Sun.COM 1590*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result_u); 1591*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(QueryUserInfo_result); 1592*11337SWilliam.Krier@Sun.COM DECL_FIXUP_STRUCT(samr_QueryUserInfo); 1593*11337SWilliam.Krier@Sun.COM 1594*11337SWilliam.Krier@Sun.COM void 1595*11337SWilliam.Krier@Sun.COM fixup_samr_QueryAliasInfo(struct samr_QueryAliasInfo *val) 1596*11337SWilliam.Krier@Sun.COM { 1597*11337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 1598*11337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 1599*11337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 1600*11337SWilliam.Krier@Sun.COM 1601*11337SWilliam.Krier@Sun.COM switch (val->level) { 1602*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 1); 1603*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryAliasInfo, 3); 1604*11337SWilliam.Krier@Sun.COM 1605*11337SWilliam.Krier@Sun.COM default: 1606*11337SWilliam.Krier@Sun.COM return; 1607*11337SWilliam.Krier@Sun.COM }; 1608*11337SWilliam.Krier@Sun.COM 1609*11337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 1610*11337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1611*11337SWilliam.Krier@Sun.COM 1612*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo_ru, size1); 1613*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfoRes, size2); 1614*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryAliasInfo, size3); 1615*11337SWilliam.Krier@Sun.COM } 1616*11337SWilliam.Krier@Sun.COM 1617*11337SWilliam.Krier@Sun.COM void 1618*11337SWilliam.Krier@Sun.COM fixup_samr_QueryUserInfo(struct samr_QueryUserInfo *val) 1619*11337SWilliam.Krier@Sun.COM { 1620*11337SWilliam.Krier@Sun.COM unsigned short size1 = 0; 1621*11337SWilliam.Krier@Sun.COM unsigned short size2 = 0; 1622*11337SWilliam.Krier@Sun.COM unsigned short size3 = 0; 1623*11337SWilliam.Krier@Sun.COM 1624*11337SWilliam.Krier@Sun.COM switch (val->switch_index) { 1625*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 1); 1626*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 6); 1627*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 7); 1628*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 8); 1629*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 9); 1630*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 16); 1631*11337SWilliam.Krier@Sun.COM CASE_INFO_ENT(samr_QueryUserInfo, 21); 1632*11337SWilliam.Krier@Sun.COM 1633*11337SWilliam.Krier@Sun.COM default: 1634*11337SWilliam.Krier@Sun.COM return; 1635*11337SWilliam.Krier@Sun.COM }; 1636*11337SWilliam.Krier@Sun.COM 1637*11337SWilliam.Krier@Sun.COM size2 = size1 + (2 * sizeof (DWORD)); 1638*11337SWilliam.Krier@Sun.COM size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD); 1639*11337SWilliam.Krier@Sun.COM 1640*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result_u, size1); 1641*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(QueryUserInfo_result, size2); 1642*11337SWilliam.Krier@Sun.COM FIXUP_PDU_SIZE(samr_QueryUserInfo, size3); 1643*11337SWilliam.Krier@Sun.COM } 1644*11337SWilliam.Krier@Sun.COM 1645*11337SWilliam.Krier@Sun.COM /* 1646*11337SWilliam.Krier@Sun.COM * As long as there is only one entry in the union, there is no need 1647*11337SWilliam.Krier@Sun.COM * to patch anything. 1648*11337SWilliam.Krier@Sun.COM */ 1649*11337SWilliam.Krier@Sun.COM /*ARGSUSED*/ 1650*11337SWilliam.Krier@Sun.COM void 1651*11337SWilliam.Krier@Sun.COM fixup_samr_QueryGroupInfo(struct samr_QueryGroupInfo *val) 1652*11337SWilliam.Krier@Sun.COM { 1653*11337SWilliam.Krier@Sun.COM } 1654