1/* 2 * Unix SMB/CIFS implementation. 3 * NetUserEnum query 4 * Copyright (C) Guenther Deschner 2007 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20#include <sys/types.h> 21#include <inttypes.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include <netapi.h> 27 28#include "common.h" 29 30int main(int argc, const char **argv) 31{ 32 NET_API_STATUS status; 33 struct libnetapi_ctx *ctx = NULL; 34 const char *hostname = NULL; 35 uint32_t level = 0; 36 uint8_t *buffer = NULL; 37 uint32_t entries_read = 0; 38 uint32_t total_entries = 0; 39 uint32_t resume_handle = 0; 40 char *sid_str = NULL; 41 int i; 42 43 struct USER_INFO_0 *info0 = NULL; 44 struct USER_INFO_10 *info10 = NULL; 45 struct USER_INFO_20 *info20 = NULL; 46 struct USER_INFO_23 *info23 = NULL; 47 48 poptContext pc; 49 int opt; 50 51 struct poptOption long_options[] = { 52 POPT_AUTOHELP 53 POPT_COMMON_LIBNETAPI_EXAMPLES 54 POPT_TABLEEND 55 }; 56 57 status = libnetapi_init(&ctx); 58 if (status != 0) { 59 return status; 60 } 61 62 pc = poptGetContext("user_enum", argc, argv, long_options, 0); 63 64 poptSetOtherOptionHelp(pc, "hostname level"); 65 while((opt = poptGetNextOpt(pc)) != -1) { 66 } 67 68 if (!poptPeekArg(pc)) { 69 poptPrintHelp(pc, stderr, 0); 70 goto out; 71 } 72 hostname = poptGetArg(pc); 73 74 if (poptPeekArg(pc)) { 75 level = atoi(poptGetArg(pc)); 76 } 77 78 /* NetUserEnum */ 79 80 do { 81 status = NetUserEnum(hostname, 82 level, 83 FILTER_NORMAL_ACCOUNT, 84 &buffer, 85 (uint32_t)-1, 86 &entries_read, 87 &total_entries, 88 &resume_handle); 89 if (status == 0 || status == ERROR_MORE_DATA) { 90 91 switch (level) { 92 case 0: 93 info0 = (struct USER_INFO_0 *)buffer; 94 break; 95 case 10: 96 info10 = (struct USER_INFO_10 *)buffer; 97 break; 98 case 20: 99 info20 = (struct USER_INFO_20 *)buffer; 100 break; 101 case 23: 102 info23 = (struct USER_INFO_23 *)buffer; 103 break; 104 default: 105 break; 106 } 107 108 for (i=0; i<entries_read; i++) { 109 switch (level) { 110 case 0: 111 printf("#%d user: %s\n", i, info0->usri0_name); 112 info0++; 113 break; 114 case 10: 115 printf("#%d user: %s\n", i, info10->usri10_name); 116 printf("#%d comment: %s\n", i, info10->usri10_comment); 117 printf("#%d usr_comment: %s\n", i, info10->usri10_usr_comment); 118 printf("#%d full_name: %s\n", i, info10->usri10_full_name); 119 info10++; 120 break; 121 case 20: 122 printf("#%d user: %s\n", i, info20->usri20_name); 123 printf("#%d comment: %s\n", i, info20->usri20_comment); 124 printf("#%d flags: 0x%08x\n", i, info20->usri20_flags); 125 printf("#%d rid: %d\n", i, info20->usri20_user_id); 126 info20++; 127 break; 128 case 23: 129 printf("#%d user: %s\n", i, info23->usri23_name); 130 printf("#%d comment: %s\n", i, info23->usri23_comment); 131 printf("#%d flags: 0x%08x\n", i, info23->usri23_flags); 132 if (ConvertSidToStringSid(info23->usri23_user_sid, 133 &sid_str)) { 134 printf("#%d sid: %s\n", i, sid_str); 135 free(sid_str); 136 } 137 info23++; 138 break; 139 default: 140 break; 141 } 142 } 143 NetApiBufferFree(buffer); 144 } 145 } while (status == ERROR_MORE_DATA); 146 147 if (status != 0) { 148 printf("NetUserEnum failed with: %s\n", 149 libnetapi_get_error_string(ctx, status)); 150 } 151 152 out: 153 libnetapi_free(ctx); 154 poptFreeContext(pc); 155 156 return status; 157} 158