/* * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "LsarLookup.h" #include "SetNetworkAccountSID.h" #include #define MAX_SID_PRINTBUFFER 256 /* Used to print out the sid in case of an error */ /* * print_ntsid * * Take a nt style sid and convert it into a printable string. */ static void print_ntsid(ntsid_t *sidptr, const char *printstr) { char sidprintbuf[MAX_SID_PRINTBUFFER]; char *s = sidprintbuf; int subs; uint64_t auth = 0; unsigned i; uint32_t *ip; size_t len; bzero(sidprintbuf, MAX_SID_PRINTBUFFER); for (i = 0; i < sizeof(sidptr->sid_authority); i++) auth = (auth << 8) | sidptr->sid_authority[i]; s += snprintf(s, MAX_SID_PRINTBUFFER, "S-%u-%llu", sidptr->sid_kind, auth); subs = sidptr->sid_authcount; for (ip = sidptr->sid_authorities; subs--; ip++) { len = MAX_SID_PRINTBUFFER - (s - sidprintbuf); s += snprintf(s, len, "-%u", *ip); } fprintf(stdout, "%-16s%s \n", printstr, sidprintbuf); } /* * get_local_sid * * Take the local users uid, use that to obtain the uuid and then use * the uuid to to obtain the nt style sid of the local user. */ static int get_local_sid(void *sid) { uuid_t uu; int error; error = mbr_uid_to_uuid(geteuid(), uu); if (!error) { error = mbr_uuid_to_sid(uu, sid); } return error; } int cmd_identity(int argc, char *argv[]) { struct passwd *pwd = NULL; const char *url = NULL; int opt; SMBHANDLE serverConnection = NULL; uint64_t options = 0; NTSTATUS status; SMBServerPropertiesV1 properties; char *AccountName = NULL, *DomainName = NULL; ntsid_t *sid = NULL; ntsid_t localSid; while ((opt = getopt(argc, argv, "N")) != EOF) { switch(opt){ case 'N': options |= kSMBOptionNoPrompt; break; default: identity_usage(); /*NOTREACHED*/ } } if (optind >= argc) identity_usage(); url = argv[optind]; argc -= optind; /* One more check to make sure we have the correct number of arguments */ if (argc != 1) identity_usage(); status = SMBOpenServerEx(url, &serverConnection, options); /* * SMBOpenServerEx now sets errno, so err will work correctly. We change * the string based on the NTSTATUS Error. */ if (!NT_SUCCESS(status)) { /* This routine will exit the program */ ntstatus_to_err(status); } status = SMBGetServerProperties(serverConnection, &properties, kPropertiesVersion, sizeof(properties)); if (!NT_SUCCESS(status)) { err(EX_UNAVAILABLE, "internal error"); } /* Only use RPC if the server supports DCE/RPC and UNICODE */ if (properties.capabilities & SMB_CAP_RPC_REMOTE_APIS) { status = GetNetworkAccountSID(properties.serverName, &AccountName, &DomainName, &sid); } else { status = STATUS_NOT_SUPPORTED; } if (!NT_SUCCESS(status)) { /* This routine will exit the program */ ntstatus_to_err(status); } fprintf(stdout, "\n"); if (AccountName) { fprintf(stdout, "%-16s%s\n", "Network User:", AccountName); free(AccountName); } else { fprintf(stdout, "%-16s%s\n", "Network User:", "UNKNOWN"); } if (DomainName) { fprintf(stdout, "%-16s%s\n", "Network Domain:", DomainName); free(DomainName); } else { fprintf(stdout, "%-16s%s\n", "Network Domain:", "UNKNOWN"); } if (sid) { print_ntsid(sid, "Network SID:"); free(sid); } else { fprintf(stdout, "%-16s%s\n", "Network SID:", "UNKNOWN"); } /* * Remmeber the contents of this data structure is automatically released by * subsequent calls to any of these rou tines on the same thread, or when * the thread exits. */ pwd = getpwuid(geteuid()); if (pwd && pwd->pw_name) { fprintf(stdout, "%-16s%s\n", "Local User:", pwd->pw_name); } else { fprintf(stdout, "Local User UNKNOWN\n"); } if (get_local_sid(&localSid) == 0) { print_ntsid(&localSid, "Local SID:"); } else { fprintf(stdout, "%-16s%s\n", "Local SID:", "UNKNOWN"); } SMBReleaseServer(serverConnection); return 0; } void identity_usage(void) { fprintf(stderr, "usage: smbutil identity [connection options] //" "[domain;][user[:password]@]" "server\n"); fprintf(stderr, "where options are:\n" " -N don't prompt for a password\n"); exit(1); }