GCC Code Coverage Report


Directory: src/gate/
File: src/gate/system/accounts.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 35 105 33.3%
Functions: 4 18 22.2%
Branches: 8 24 33.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/system/accounts.h"
30 #include "gate/results.h"
31 #include "gate/debugging.h"
32
33 #if defined(GATE_SYS_WIN) && !defined(GATE_SYS_WINCE) && !defined(GATE_SYS_WIN16)
34 # define GATE_SYSTEM_ACCOUNTS_WINLM
35 #elif defined(GATE_SYS_POSIX)
36 # define GATE_SYSTEM_ACCOUNTS_POSIX
37 #else
38 # define GATE_SYSTEM_ACCOUNTS_NOIMPL
39 #endif
40
41
42 #if defined(GATE_SYSTEM_ACCOUNTS_WINLM)
43
44 #include "gate/system/platform/netapi_tools.h"
45
46 #ifndef MAX_PREFERRED_LENGTH
47 #define MAX_PREFERRED_LENGTH ((DWORD) -1)
48 #endif
49
50
51 static WCHAR const* gate_account_get_local_computer(WCHAR* buffer, gate_size_t buffer_length)
52 {
53 WCHAR const* ret = NULL;
54 TCHAR computer_name[32];
55 DWORD computer_name_len = sizeof(computer_name) / sizeof(computer_name[0]);
56 gate_int32_t error_code;
57
58 do
59 {
60 if (buffer_length < 4)
61 {
62 GATE_DEBUG_TRACE_MSG_VALUE("gate_account_get_local_computer() buffer too small", buffer_length);
63 break;
64 }
65
66 if (!GetComputerName(computer_name, &computer_name_len))
67 {
68 error_code = gate_platform_get_last_error();
69 GATE_DEBUG_TRACE_MSG_VALUE("gate_account_get_local_computer::GetComputerName() failed", error_code);
70 break;
71 }
72
73 buffer[0] = L'\\';
74 buffer[1] = L'\\';
75 gate_win32_winstr_2_utf16(computer_name, computer_name_len, &buffer[2],
76 buffer_length - 2);
77 ret = buffer;
78 } while (0);
79 return ret;
80 }
81
82 static gate_win32_sidstruct_t* gate_account_get_computer_sid(LPCWSTR ptr_system_name, gate_win32_sidstruct_t* ptr_sid)
83 {
84 gate_win32_sidstruct_t* ret = NULL;
85 DWORD net_status;
86 GATE_USER_MODALS_INFO_2* ptr_computer_info = NULL;
87
88 net_status = win32_netapi.NetUserModalsGet(ptr_system_name, 2, (LPBYTE*)&ptr_computer_info);
89 if (net_status == 0)
90 {
91 gate_win32_sid_export(ptr_computer_info->usrmod2_domain_id, ptr_sid);
92 win32_netapi.NetApiBufferFree(ptr_computer_info);
93 ret = ptr_sid;
94 }
95 return ret;
96 }
97
98 #define GATE_ACCOUNTS_MAX_SYSTEM_NAME 34
99
100 static void gate_account_make_user(gate_account_user_t* user_account, gate_win32_sidstruct_t const* sid,
101 LPCWSTR name, LPCWSTR info, LPCWSTR descr, DWORD flags)
102 {
103 gate_mem_clear(user_account, sizeof(gate_account_user_t));
104
105 if (sid)
106 {
107 gate_win32_sid_print(sid, user_account->id, sizeof(user_account->id));
108 user_account->short_id = sid->SubAuthorities[sid->SubAuthCount - 1];
109 }
110 gate_str_utf16_2_utf8(name, gate_str16_length(name), user_account->name, sizeof(user_account->name));
111 gate_str_utf16_2_utf8(info, gate_str16_length(info), user_account->info, sizeof(user_account->info));
112 gate_str_utf16_2_utf8(descr, gate_str16_length(descr), user_account->description, sizeof(user_account->description));
113 if (GATE_FLAG_ENABLED(flags, UF_ACCOUNTDISABLE))
114 {
115 user_account->flags |= GATE_ACCOUNT_USER_FLAG_DISABLED;
116 }
117 if (GATE_FLAG_ENABLED(flags, UF_LOCKOUT))
118 {
119 user_account->flags |= GATE_ACCOUNT_USER_FLAG_LOCKED;
120 }
121 }
122 static void gate_account_make_group(gate_account_group_t* group_account, gate_win32_sidstruct_t const* sid,
123 LPCWSTR name, LPCWSTR descr, DWORD flags)
124 {
125 GATE_UNUSED_ARG(flags);
126 gate_mem_clear(group_account, sizeof(gate_account_group_t));
127
128 if (sid)
129 {
130 gate_win32_sid_print(sid, group_account->id, sizeof(group_account->id));
131 group_account->short_id = sid->SubAuthorities[sid->SubAuthCount - 1];
132 }
133 gate_str_utf16_2_utf8(name, gate_str16_length(name), group_account->name, sizeof(group_account->name));
134 gate_str_utf16_2_utf8(descr, gate_str16_length(descr), group_account->description, sizeof(group_account->description));
135 }
136
137
138 gate_result_t gate_account_enum_users(gate_account_enum_users_callback_t callback, void* param)
139 {
140 gate_result_t ret = GATE_RESULT_FAILED;
141 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
142 WCHAR const* ptr_system_name = NULL;
143 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
144 gate_win32_sidstruct_t* ptr_sid = NULL;
145 DWORD net_status;
146 DWORD next_info_index = 0;
147 PVOID info_buffer = NULL;
148 DWORD infos_returned;
149 GATE_NET_DISPLAY_USER* ptr_user;
150 gate_account_user_t user_account;
151 gate_bool_t continue_enum = true;
152
153 do
154 {
155 if (!load_netapi() || (NULL == win32_netapi.NetQueryDisplayInformation))
156 {
157 ret = GATE_RESULT_NOTSUPPORTED;
158 break;
159 }
160
161 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
162
163 if (gate_account_get_computer_sid(ptr_system_name, &sid))
164 {
165 sid.SubAuthorities[sid.SubAuthCount] = 0;
166 ++sid.SubAuthCount;
167 ptr_sid = &sid;
168 }
169
170 ret = GATE_RESULT_OK;
171 do
172 {
173 net_status = win32_netapi.NetQueryDisplayInformation(
174 ptr_system_name, 1, next_info_index, 32, MAX_PREFERRED_LENGTH, &infos_returned, &info_buffer);
175 if ((ERROR_MORE_DATA != net_status) && (ERROR_SUCCESS != net_status))
176 {
177 ret = GATE_RESULT_FAILED;
178 break;
179 }
180 if (infos_returned == 0)
181 {
182 /* all accounts returned */
183 break;
184 }
185
186 ptr_user = (GATE_NET_DISPLAY_USER*)info_buffer;
187
188 while (continue_enum && (infos_returned-- > 0))
189 {
190 if (ptr_sid)
191 {
192 ptr_sid->SubAuthorities[ptr_sid->SubAuthCount - 1] = ptr_user->usri1_user_id;
193 }
194
195 gate_account_make_user(&user_account, ptr_sid, ptr_user->usri1_name,
196 ptr_user->usri1_full_name, ptr_user->usri1_comment, ptr_user->usri1_flags);
197
198 next_info_index = ptr_user->usri1_next_index;
199 ++ptr_user;
200
201 if (callback)
202 {
203 continue_enum = callback(&user_account, param);
204 }
205 }
206 win32_netapi.NetApiBufferFree(info_buffer);
207 } while ((net_status == ERROR_MORE_DATA) && continue_enum);
208 } while (0);
209 return ret;
210 }
211 gate_result_t gate_account_enum_groups(gate_account_enum_groups_callback_t callback, void* param)
212 {
213 gate_result_t ret = GATE_RESULT_FAILED;
214 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
215 WCHAR const* ptr_system_name = NULL;
216 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
217 DWORD sid_length = sizeof(&sid);
218 WCHAR referenced_domain[256];
219 DWORD referenced_domain_len;
220 DWORD net_status;
221 PVOID info_buffer = NULL;
222 DWORD infos_returned;
223 DWORD infos_total = 0;
224 DWORD_PTR resume_handle = 0;
225 GATE_LOCALGROUP_INFO_1* ptr_group;
226 SID_NAME_USE sid_name_use;
227 gate_account_group_t group_account;
228 gate_bool_t continue_enum = true;
229
230 do
231 {
232 if (!load_netapi() || !win32_netapi.NetLocalGroupEnum || !gate_platform.AdvLookupAccountNameW)
233 {
234 ret = GATE_RESULT_NOTSUPPORTED;
235 break;
236 }
237
238 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
239
240 ret = GATE_RESULT_OK;
241
242 do
243 {
244 net_status = win32_netapi.NetLocalGroupEnum(ptr_system_name, 1, (LPBYTE*)&ptr_group, MAX_PREFERRED_LENGTH, &infos_returned, &infos_total, &resume_handle);
245 if ((ERROR_MORE_DATA != net_status) && (ERROR_SUCCESS != net_status))
246 {
247 ret = GATE_RESULT_FAILED;
248 break;
249 }
250 if (infos_returned == 0)
251 {
252 break;
253 }
254 while (continue_enum && (infos_returned-- > 0))
255 {
256 gate_mem_clear(&group_account, sizeof(group_account));
257
258 sid_length = sizeof(sid);
259 referenced_domain_len = sizeof(referenced_domain) / sizeof(referenced_domain[0]);
260 if (gate_platform.AdvLookupAccountNameW(NULL, ptr_group->lgrpi1_name, &sid, &sid_length,
261 referenced_domain, &referenced_domain_len, &sid_name_use))
262 {
263 gate_win32_sid_print(&sid, group_account.id, sizeof(group_account.id));
264 if (sid.SubAuthCount > 0)
265 {
266 group_account.short_id = sid.SubAuthorities[sid.SubAuthCount - 1];
267 }
268 }
269
270 gate_str_utf16_2_utf8(ptr_group->lgrpi1_name, gate_str16_length(ptr_group->lgrpi1_name),
271 group_account.name, sizeof(group_account.name));
272 gate_str_utf16_2_utf8(ptr_group->lgrpi1_comment, gate_str16_length(ptr_group->lgrpi1_comment),
273 group_account.description, sizeof(group_account.description));
274
275 ++ptr_group;
276
277 if (callback)
278 {
279 continue_enum = callback(&group_account, param);
280 }
281 }
282 win32_netapi.NetApiBufferFree(info_buffer);
283
284 } while ((net_status == ERROR_MORE_DATA) && continue_enum);
285
286 } while (0);
287 return ret;
288 }
289 gate_result_t gate_account_enum_group_members(gate_account_group_t const* group, gate_account_enum_users_callback_t callback, void* param)
290 {
291 gate_result_t ret = GATE_RESULT_FAILED;
292 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
293 WCHAR const* ptr_system_name;
294 WCHAR group_name[256];
295 GATE_LOCALGROUP_MEMBERS_INFO_1* ptr_member_info = NULL;
296 DWORD entries_read = 0;
297 DWORD total_entries = 0;
298 DWORD_PTR resume_handle = 0;
299 DWORD net_status = 0;
300 DWORD index;
301 gate_account_user_t user;
302 gate_bool_t continue_enum = true;
303
304 do
305 {
306 if (!load_netapi() || !win32_netapi.NetLocalGroupGetMembers)
307 {
308 ret = GATE_RESULT_NOTSUPPORTED;
309 break;
310 }
311
312 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
313 gate_str_utf8_2_utf16(group->name, gate_str_length(group->name), group_name, sizeof(group_name) / sizeof(group_name[0]));
314 ret = GATE_RESULT_OK;
315 do
316 {
317 net_status = win32_netapi.NetLocalGroupGetMembers(ptr_system_name, group_name, 1,
318 (LPBYTE*)&ptr_member_info, MAX_PREFERRED_LENGTH, &entries_read, &total_entries, &resume_handle);
319 if ((ERROR_MORE_DATA != net_status) && (0 != net_status))
320 {
321 ret = GATE_RESULT_FAILED;
322 break;
323 }
324
325 for (index = 0; index < entries_read; ++index)
326 {
327 gate_mem_clear(&user, sizeof(user));
328 if (SidTypeUser == ptr_member_info[index].lgrmi1_sidusage)
329 {
330 gate_account_make_user(&user, (gate_win32_sidstruct_t const*)ptr_member_info[index].lgrmi1_sid,
331 ptr_member_info[index].lgrmi1_name, NULL, NULL, 0);
332 if (!callback(&user, param))
333 {
334 continue_enum = false;
335 break;
336 }
337 }
338 }
339
340 win32_netapi.NetApiBufferFree(ptr_member_info);
341
342 } while ((ERROR_MORE_DATA == net_status) && continue_enum);
343 } while (0);
344 return ret;
345 }
346 gate_result_t gate_account_enum_user_memberships(gate_account_user_t const* user, gate_account_enum_groups_callback_t callback, void* param)
347 {
348 gate_result_t ret = GATE_RESULT_FAILED;
349 gate_result_t result;
350 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
351 WCHAR const* ptr_system_name;
352 WCHAR user_name[256];
353 GATE_LOCALGROUP_USERS_INFO_0* ptr_group_info = NULL;
354 DWORD entries_returned = 0;
355 DWORD entries_total = 0;
356 DWORD index;
357 DWORD net_status = 0;
358 gate_bool_t continue_enum = true;
359 char localgroup_name[256];
360 gate_size_t localgroup_name_len;
361 gate_string_t localgroup_str;
362 gate_account_group_t group;
363
364 do
365 {
366 if (!load_netapi() || !win32_netapi.NetUserGetLocalGroups)
367 {
368 ret = GATE_RESULT_NOTSUPPORTED;
369 break;
370 }
371
372 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
373 gate_str_utf8_2_utf16(user->name, gate_str_length(user->name), user_name, sizeof(user_name) / sizeof(user_name[0]));
374
375 do
376 {
377 net_status = win32_netapi.NetUserGetLocalGroups(ptr_system_name, user_name, 0, LG_INCLUDE_INDIRECT,
378 (LPBYTE*)&ptr_group_info, MAX_PREFERRED_LENGTH, &entries_returned, &entries_total);
379
380 if ((ERROR_MORE_DATA != net_status) && (0 != net_status))
381 {
382 ret = GATE_RESULT_FAILED;
383 break;
384 }
385
386 for (index = 0; index < entries_returned; ++index)
387 {
388 localgroup_name_len = gate_str_utf16_2_utf8(ptr_group_info[index].lgrui0_name,
389 gate_str16_length(ptr_group_info[index].lgrui0_name),
390 localgroup_name, sizeof(localgroup_name));
391 gate_string_create_static_len(&localgroup_str, localgroup_name, localgroup_name_len);
392 result = gate_account_resolve_group(&localgroup_str, &group);
393 if (GATE_SUCCEEDED(result))
394 {
395 if (!callback(&group, param))
396 {
397 continue_enum = false;
398 break;
399 }
400 }
401 }
402
403 win32_netapi.NetApiBufferFree(ptr_group_info);
404
405 } while ((ERROR_MORE_DATA == net_status) && continue_enum);
406
407 ret = GATE_RESULT_OK;
408 } while (0);
409
410 return ret;
411 }
412 gate_result_t gate_account_get_user(gate_string_t const* user_id, gate_account_user_t* user)
413 {
414 gate_result_t ret = GATE_RESULT_FAILED;
415 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
416 WCHAR const* ptr_system_name = NULL;
417 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
418 PSID psid = NULL;
419 WCHAR user_name[256];
420 DWORD user_name_len = sizeof(user_name) / sizeof(user_name[0]);
421 WCHAR domain_name[256];
422 DWORD domain_name_len = sizeof(domain_name) / sizeof(domain_name[0]);
423 SID_NAME_USE sid_type = (SID_NAME_USE)0;
424 GATE_USER_INFO_2* ptr_user_info = NULL;
425 DWORD net_status;
426 LPCWSTR ptr_full_name;
427 LPCWSTR ptr_comment;
428 DWORD user_flags;
429
430 do
431 {
432 if (!load_netapi() || !gate_platform.AdvLookupAccountSidW || !win32_netapi.NetUserGetInfo)
433 {
434 ret = GATE_RESULT_NOTSUPPORTED;
435 break;
436 }
437 psid = gate_win32_sid_parse(gate_string_ptr(user_id, 0), (DWORD)gate_string_length(user_id), &sid);
438 if (!psid)
439 {
440 ret = GATE_RESULT_INVALIDARG;
441 break;
442 }
443
444 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
445 if (!gate_platform.AdvLookupAccountSidW(ptr_system_name, psid, user_name, &user_name_len,
446 domain_name, &domain_name_len, &sid_type))
447 {
448 ret = GATE_RESULT_NOMATCH;
449 break;
450 }
451 if (sid_type != SidTypeUser)
452 {
453 ret = GATE_RESULT_NOMATCH;
454 break;
455 }
456
457
458 /* fill optional fields: */
459 ptr_full_name = NULL;
460 ptr_comment = NULL;
461 user_flags = 0;
462 ptr_user_info = NULL;
463
464 net_status = win32_netapi.NetUserGetInfo(ptr_system_name, user_name, 2, (LPBYTE*)&ptr_user_info);
465 if (0 == net_status)
466 {
467 ptr_full_name = ptr_user_info->usri2_full_name;
468 ptr_comment = ptr_user_info->usri2_comment;
469 user_flags = ptr_user_info->usri2_flags;
470 }
471
472 gate_account_make_user(user, &sid, user_name, ptr_full_name, ptr_comment, user_flags);
473 ret = GATE_RESULT_OK;
474 } while (0);
475
476 if (ptr_user_info != NULL)
477 {
478 win32_netapi.NetApiBufferFree(ptr_user_info);
479 }
480
481 return ret;
482 }
483 gate_result_t gate_account_resolve_user(gate_string_t const* user_name, gate_account_user_t* user)
484 {
485 gate_result_t ret = GATE_RESULT_FAILED;
486 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
487 WCHAR const* ptr_system_name = NULL;
488 WCHAR account_name[256];
489 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
490 gate_win32_sidstruct_t* ptr_sid = NULL;
491 DWORD net_status;
492 GATE_USER_INFO_3* ptr_user_info = NULL;
493
494 do
495 {
496 if (!load_netapi() || !win32_netapi.NetUserGetInfo)
497 {
498 ret = GATE_RESULT_NOTSUPPORTED;
499 break;
500 }
501
502 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
503
504 gate_str_utf8_2_utf16(user_name->str, user_name->length, account_name, sizeof(account_name) / sizeof(account_name[0]));
505 net_status = win32_netapi.NetUserGetInfo(ptr_system_name, account_name, 3, (LPBYTE*)&ptr_user_info);
506 if (0 != net_status)
507 {
508 ret = GATE_RESULT_NOTAVAILABLE;
509 break;
510 }
511
512 ret = GATE_RESULT_OK;
513
514 if (gate_account_get_computer_sid(ptr_system_name, &sid))
515 {
516 sid.SubAuthorities[sid.SubAuthCount] = ptr_user_info->usri3_user_id;
517 ++sid.SubAuthCount;
518 ptr_sid = &sid;
519 }
520
521 gate_account_make_user(user, ptr_sid, ptr_user_info->usri3_name, ptr_user_info->usri3_full_name,
522 ptr_user_info->usri3_comment, ptr_user_info->usri3_flags);
523
524 win32_netapi.NetApiBufferFree(ptr_user_info);
525 } while (0);
526
527 return ret;
528 }
529
530 gate_result_t gate_account_get_group(gate_string_t const* group_id, gate_account_group_t* group)
531 {
532 gate_result_t ret = GATE_RESULT_FAILED;
533 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
534 WCHAR const* ptr_system_name = NULL;
535 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
536 PSID psid = NULL;
537 WCHAR group_name[256];
538 DWORD group_name_len = sizeof(group_name) / sizeof(group_name[0]);
539 WCHAR domain_name[256];
540 DWORD domain_name_len = sizeof(domain_name) / sizeof(domain_name[0]);
541 SID_NAME_USE sid_name_use;
542 GATE_LOCALGROUP_INFO_1* ptr_localgroup_info = NULL;
543 LPCWSTR ptr_comment = NULL;
544 DWORD net_status = 0;
545
546
547 do
548 {
549 if (!load_netapi() || !gate_platform.AdvLookupAccountSidW || !win32_netapi.NetLocalGroupGetInfo)
550 {
551 ret = GATE_RESULT_NOTSUPPORTED;
552 break;
553 }
554
555 psid = gate_win32_sid_parse(gate_string_ptr(group_id, 0), (DWORD)gate_string_length(group_id), &sid);
556 if (!psid)
557 {
558 ret = GATE_RESULT_INVALIDARG;
559 break;
560 }
561
562 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
563 if (!gate_platform.AdvLookupAccountSidW(ptr_system_name, psid, group_name, &group_name_len,
564 domain_name, &domain_name_len, &sid_name_use))
565 {
566 ret = GATE_RESULT_NOMATCH;
567 break;
568 }
569 if ((sid_name_use != SidTypeGroup) && (sid_name_use != SidTypeAlias) && (sid_name_use != SidTypeWellKnownGroup))
570 {
571 ret = GATE_RESULT_NOMATCH;
572 break;
573 }
574
575 ret = GATE_RESULT_OK;
576 ptr_comment = NULL;
577
578 net_status = win32_netapi.NetLocalGroupGetInfo(ptr_system_name, group_name, 1, (LPBYTE*)&ptr_localgroup_info);
579 if (0 == net_status)
580 {
581 ptr_comment = ptr_localgroup_info->lgrpi1_comment;
582 }
583
584 gate_account_make_group(group, &sid, group_name, ptr_comment, 0);
585
586 } while (0);
587
588 if (ptr_localgroup_info)
589 {
590 win32_netapi.NetApiBufferFree(ptr_localgroup_info);
591 }
592 return ret;
593 }
594 gate_result_t gate_account_resolve_group(gate_string_t const* group_name, gate_account_group_t* group)
595 {
596 gate_result_t ret = GATE_RESULT_FAILED;
597 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
598 WCHAR const* ptr_system_name = NULL;
599 WCHAR account_group[256];
600 gate_win32_sidstruct_t sid;
601 DWORD sid_length = sizeof(sid);
602 DWORD net_status;
603 GATE_LOCALGROUP_INFO_1* ptr_group_info = NULL;
604 LPCWSTR ptr_comment = NULL;
605 WCHAR domain[256];
606 DWORD domain_len = sizeof(domain) / sizeof(domain[0]);
607 SID_NAME_USE sid_name_use;
608
609 do
610 {
611 if (!load_netapi() || !gate_platform.AdvLookupAccountNameW || !win32_netapi.NetLocalGroupGetInfo)
612 {
613 ret = GATE_RESULT_NOTSUPPORTED;
614 break;
615 }
616
617 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
618 gate_str_utf8_2_utf16(group_name->str, group_name->length, account_group, sizeof(account_group) / sizeof(account_group[0]));
619
620 if (!gate_platform.AdvLookupAccountNameW(ptr_system_name, account_group, &sid, &sid_length, domain, &domain_len, &sid_name_use))
621 {
622 ret = GATE_RESULT_NOMATCH;
623 break;
624 }
625
626 ret = GATE_RESULT_OK;
627 net_status = win32_netapi.NetLocalGroupGetInfo(ptr_system_name, account_group, 1, (LPBYTE*)&ptr_group_info);
628 if (0 == net_status)
629 {
630 ptr_comment = ptr_group_info->lgrpi1_comment;
631 }
632
633 gate_account_make_group(group, &sid, account_group, ptr_comment, 0);
634
635 if (ptr_group_info)
636 {
637 win32_netapi.NetApiBufferFree(ptr_group_info);
638 }
639 } while (0);
640
641 return ret;
642 }
643 gate_result_t gate_account_create_user(gate_string_t const* user_name, gate_string_t const* password)
644 {
645 gate_result_t ret = GATE_RESULT_FAILED;
646 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
647 WCHAR const* ptr_system_name = NULL;
648 WCHAR w_user_name[256] = GATE_INIT_EMPTY;
649 WCHAR w_user_passwd[256] = GATE_INIT_EMPTY;
650 GATE_USER_INFO_1 user_info_1 = GATE_INIT_EMPTY;
651 DWORD param_error_index = 0;
652 DWORD net_status;
653
654 do
655 {
656 if (!load_netapi() || !win32_netapi.NetUserAdd)
657 {
658 ret = GATE_RESULT_NOTSUPPORTED;
659 break;
660 }
661
662 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
663 gate_str_utf8_2_utf16(user_name->str, user_name->length, w_user_name, sizeof(w_user_name) / sizeof(w_user_name[0]));
664 gate_str_utf8_2_utf16(gate_string_ptr(password, 0), gate_string_length(password), w_user_passwd, sizeof(w_user_passwd) / sizeof(w_user_passwd[0]));
665
666 user_info_1.usri1_name = w_user_name;
667 user_info_1.usri1_password = password ? w_user_passwd : NULL;
668 user_info_1.usri1_password_age = 0;
669 user_info_1.usri1_priv = USER_PRIV_USER;
670 user_info_1.usri1_home_dir = NULL;
671 user_info_1.usri1_comment = NULL;
672 user_info_1.usri1_flags = UF_NORMAL_ACCOUNT | (password ? 0 : UF_PASSWD_NOTREQD);
673 user_info_1.usri1_script_path = NULL;
674
675 net_status = win32_netapi.NetUserAdd(ptr_system_name, 1, (LPBYTE)&user_info_1, &param_error_index);
676 if (net_status == 0)
677 {
678 ret = GATE_RESULT_OK;
679 }
680 else
681 {
682 ret = GATE_RESULT_FAILED;
683 }
684 } while (0);
685
686 return ret;
687 }
688 gate_result_t gate_account_delete_user(gate_account_user_t const* user)
689 {
690 gate_result_t ret = GATE_RESULT_FAILED;
691 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
692 WCHAR const* ptr_system_name = NULL;
693 WCHAR user_name[256];
694 DWORD net_status;
695
696 do
697 {
698 if (!load_netapi() || !win32_netapi.NetUserDel)
699 {
700 ret = GATE_RESULT_NOTSUPPORTED;
701 break;
702 }
703
704 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
705 gate_str_utf8_2_utf16(user->name, gate_str_length(user->name), user_name, sizeof(user_name) / sizeof(user_name[0]));
706
707 net_status = win32_netapi.NetUserDel(ptr_system_name, user_name);
708 if (net_status == 0)
709 {
710 ret = GATE_RESULT_OK;
711 }
712 else
713 {
714 ret = GATE_RESULT_FAILED;
715 }
716 } while (0);
717
718 return ret;
719 }
720 gate_result_t gate_account_create_group(gate_string_t const* group_name)
721 {
722 gate_result_t ret = GATE_RESULT_FAILED;
723 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
724 WCHAR const* ptr_system_name = NULL;
725 WCHAR w_group_name[256];
726 GATE_LOCALGROUP_INFO_0 group_info_0 = GATE_INIT_EMPTY;
727 DWORD param_error_index = 0;
728 DWORD net_status;
729
730 do
731 {
732 if (!load_netapi() || !win32_netapi.NetLocalGroupAdd)
733 {
734 ret = GATE_RESULT_NOTSUPPORTED;
735 break;
736 }
737
738 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
739 gate_str_utf8_2_utf16(group_name->str, group_name->length, w_group_name, sizeof(w_group_name) / sizeof(w_group_name[0]));
740
741 group_info_0.lgrpi0_name = w_group_name;
742
743 net_status = win32_netapi.NetLocalGroupAdd(ptr_system_name, 0, (LPBYTE)&group_info_0, &param_error_index);
744 if (net_status == 0)
745 {
746 ret = GATE_RESULT_OK;
747 }
748 else
749 {
750 ret = GATE_RESULT_FAILED;
751 }
752 } while (0);
753
754 return ret;
755 }
756 gate_result_t gate_account_delete_group(gate_account_group_t const* group)
757 {
758 gate_result_t ret = GATE_RESULT_FAILED;
759 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
760 WCHAR const* ptr_system_name = NULL;
761 WCHAR group_name[256];
762 DWORD net_status;
763
764 do
765 {
766 if (!load_netapi() || !win32_netapi.NetLocalGroupDel)
767 {
768 ret = GATE_RESULT_NOTSUPPORTED;
769 break;
770 }
771
772 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
773 gate_str_utf8_2_utf16(group->name, gate_str_length(group->name), group_name, sizeof(group_name) / sizeof(group_name[0]));
774
775 net_status = win32_netapi.NetLocalGroupDel(ptr_system_name, group_name);
776 if (net_status == 0)
777 {
778 ret = GATE_RESULT_OK;
779 }
780 else
781 {
782 ret = GATE_RESULT_FAILED;
783 }
784 } while (0);
785
786 return ret;
787 }
788
789 gate_result_t gate_account_add_user_to_group(gate_account_user_t const* user, gate_account_group_t const* group)
790 {
791 gate_result_t ret = GATE_RESULT_FAILED;
792 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
793 WCHAR const* ptr_system_name = NULL;
794 WCHAR group_name[256];
795 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
796 DWORD net_status;
797 GATE_LOCALGROUP_MEMBERS_INFO_0 member_info_0;
798
799 do
800 {
801 if (!load_netapi() || !win32_netapi.NetLocalGroupAddMembers)
802 {
803 ret = GATE_RESULT_NOTSUPPORTED;
804 break;
805 }
806
807 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
808 gate_str_utf8_2_utf16(group->name, gate_str_length(group->name), group_name, sizeof(group_name) / sizeof(group_name[0]));
809
810 gate_mem_clear(&member_info_0, sizeof(member_info_0));
811 member_info_0.lgrmi0_sid = gate_win32_sid_parse(user->id, (DWORD)gate_str_length(user->id), &sid);
812
813 net_status = win32_netapi.NetLocalGroupAddMembers(ptr_system_name, group_name, 0, (LPBYTE)&member_info_0, 1);
814 if (net_status == 0)
815 {
816 ret = GATE_RESULT_OK;
817 }
818 else
819 {
820 ret = GATE_RESULT_FAILED;
821 }
822 } while (0);
823
824 return ret;
825 }
826 gate_result_t gate_account_remove_user_from_group(gate_account_user_t const* user, gate_account_group_t const* group)
827 {
828 gate_result_t ret = GATE_RESULT_FAILED;
829 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
830 WCHAR const* ptr_system_name = NULL;
831 WCHAR group_name[256];
832 gate_win32_sidstruct_t sid = GATE_INIT_EMPTY;
833 DWORD net_status;
834 GATE_LOCALGROUP_MEMBERS_INFO_0 member_info_0;
835
836 do
837 {
838 if (!load_netapi() || !win32_netapi.NetLocalGroupDelMembers)
839 {
840 ret = GATE_RESULT_NOTSUPPORTED;
841 break;
842 }
843
844 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
845 gate_str_utf8_2_utf16(group->name, gate_str_length(group->name), group_name, sizeof(group_name) / sizeof(group_name[0]));
846
847 gate_mem_clear(&member_info_0, sizeof(member_info_0));
848 member_info_0.lgrmi0_sid = gate_win32_sid_parse(user->id, (DWORD)gate_str_length(user->id), &sid);
849
850 net_status = win32_netapi.NetLocalGroupDelMembers(ptr_system_name, group_name, 0, (LPBYTE)&member_info_0, 1);
851 if (net_status == 0)
852 {
853 ret = GATE_RESULT_OK;
854 }
855 else
856 {
857 ret = GATE_RESULT_FAILED;
858 }
859 } while (0);
860
861 return ret;
862 }
863
864 static gate_string_t const gate_account_user_key_comment = GATE_STRING_INIT_STATIC("Comment");
865 static gate_string_t const gate_account_user_key_full_name = GATE_STRING_INIT_STATIC("FullName");
866 static gate_string_t const gate_account_user_key_home_dir = GATE_STRING_INIT_STATIC("HomeDirectory");
867 static gate_string_t const gate_account_user_key_script_path = GATE_STRING_INIT_STATIC("ScriptPath");
868 static gate_string_t const gate_account_user_key_script_enabled = GATE_STRING_INIT_STATIC("ScriptEnabled");
869 static gate_string_t const gate_account_user_key_account_disabled = GATE_STRING_INIT_STATIC("AccountDisabled");
870 static gate_string_t const gate_account_user_key_lockout = GATE_STRING_INIT_STATIC("Lockout");
871 static gate_string_t const gate_account_user_key_no_password_expiration = GATE_STRING_INIT_STATIC("NoPasswordExpiration");
872 static gate_string_t const gate_account_user_key_password_expired = GATE_STRING_INIT_STATIC("PasswordExpired");
873 static gate_string_t const gate_account_user_key_cannot_change_password = GATE_STRING_INIT_STATIC("CannotChangePassword");
874 static gate_string_t const gate_account_user_key_password_not_required = GATE_STRING_INIT_STATIC("PasswordNotRequired");
875 static gate_string_t const gate_account_user_key_home_dir_required = GATE_STRING_INIT_STATIC("HomeDirectoryRequired");
876
877 static gate_result_t gate_account_user_add_str_property(gate_property_t* prop, gate_string_t const* key, LPCWSTR str_value)
878 {
879 gate_result_t ret = GATE_RESULT_FAILED;
880 char str_buffer[4096];
881 gate_size_t str_buffer_len;
882 gate_string_t str_member = GATE_STRING_INIT_EMPTY;
883 gate_property_t member = GATE_INIT_EMPTY;
884
885 do
886 {
887 str_buffer_len = gate_str_utf16_2_utf8(str_value, gate_str16_length(str_value), str_buffer, sizeof(str_buffer));
888
889 if (NULL == gate_string_create(&str_member, str_buffer, str_buffer_len))
890 {
891 ret = GATE_RESULT_OUTOFMEMORY;
892 break;
893 }
894
895 if (NULL == gate_property_create_string(&member, &str_member))
896 {
897 ret = GATE_RESULT_OUTOFMEMORY;
898 break;
899 }
900
901 if (NULL == gate_property_member_add(prop, key, &member))
902 {
903 ret = GATE_RESULT_OUTOFMEMORY;
904 break;
905 }
906 ret = GATE_RESULT_OK;
907 } while (0);
908
909 gate_property_destroy(&member);
910 gate_string_release(&str_member);
911
912 return ret;
913 }
914 static gate_result_t gate_account_user_add_bool_property(gate_property_t* prop, gate_string_t const* key, gate_bool_t bool_value)
915 {
916 gate_result_t ret = GATE_RESULT_FAILED;
917 gate_property_t member = GATE_INIT_EMPTY;
918
919 do
920 {
921 if (NULL == gate_property_create_bool(&member, bool_value))
922 {
923 ret = GATE_RESULT_OUTOFMEMORY;
924 break;
925 }
926
927 if (NULL == gate_property_member_add(prop, key, &member))
928 {
929 ret = GATE_RESULT_OUTOFMEMORY;
930 break;
931 }
932 ret = GATE_RESULT_OK;
933 } while (0);
934
935 gate_property_destroy(&member);
936
937 return ret;
938 }
939
940
941
942 gate_result_t gate_account_get_user_properties(gate_account_user_t const* user, gate_property_t* properties)
943 {
944 gate_result_t ret = GATE_RESULT_FAILED;
945 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
946 WCHAR const* ptr_system_name = NULL;
947 WCHAR w_user_name[256];
948 GATE_USER_INFO_2* ptr_user_info = NULL;
949 DWORD net_status;
950 gate_property_t props = GATE_INIT_EMPTY;
951
952 do
953 {
954 if (!load_netapi() || !win32_netapi.NetUserGetInfo)
955 {
956 ret = GATE_RESULT_NOTSUPPORTED;
957 break;
958 }
959
960 gate_property_create_object(&props);
961
962 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
963
964 gate_str_utf8_2_utf16(user->name, gate_str_length(user->name), w_user_name, sizeof(w_user_name) / sizeof(w_user_name[0]));
965 net_status = win32_netapi.NetUserGetInfo(ptr_system_name, w_user_name, 2, (LPBYTE*)&ptr_user_info);
966 if (0 != net_status)
967 {
968 ret = GATE_RESULT_FAILED;
969 break;
970 }
971
972 gate_account_user_add_str_property(&props, &gate_account_user_key_comment, ptr_user_info->usri2_comment);
973 gate_account_user_add_str_property(&props, &gate_account_user_key_full_name, ptr_user_info->usri2_full_name);
974 gate_account_user_add_str_property(&props, &gate_account_user_key_home_dir, ptr_user_info->usri2_home_dir);
975 gate_account_user_add_str_property(&props, &gate_account_user_key_script_path, ptr_user_info->usri2_script_path);
976
977 gate_account_user_add_bool_property(&props, &gate_account_user_key_script_enabled, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_SCRIPT));
978 gate_account_user_add_bool_property(&props, &gate_account_user_key_account_disabled, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_ACCOUNTDISABLE));
979 gate_account_user_add_bool_property(&props, &gate_account_user_key_lockout, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_LOCKOUT));
980 gate_account_user_add_bool_property(&props, &gate_account_user_key_no_password_expiration, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_DONT_EXPIRE_PASSWD));
981 gate_account_user_add_bool_property(&props, &gate_account_user_key_password_expired, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_PASSWORD_EXPIRED));
982 gate_account_user_add_bool_property(&props, &gate_account_user_key_cannot_change_password, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_PASSWD_CANT_CHANGE));
983 gate_account_user_add_bool_property(&props, &gate_account_user_key_password_not_required, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_PASSWD_NOTREQD));
984 gate_account_user_add_bool_property(&props, &gate_account_user_key_home_dir_required, GATE_FLAG_ENABLED(ptr_user_info->usri2_flags, UF_ACCOUNTDISABLE));
985
986 if (properties)
987 {
988 gate_mem_copy(properties, &props, sizeof(props));
989 gate_mem_clear(&props, sizeof(props));
990 }
991 ret = GATE_RESULT_OK;
992 } while (0);
993
994 if (ptr_user_info != NULL)
995 {
996 win32_netapi.NetApiBufferFree(ptr_user_info);
997 }
998 gate_property_destroy(&props);
999 return ret;
1000 }
1001
1002 static void gate_account_update_flag(DWORD* flag_var, DWORD flag_bit, gate_bool_t value)
1003 {
1004 if (value)
1005 {
1006 *flag_var |= flag_bit;
1007 }
1008 else
1009 {
1010 *flag_var &= ~flag_bit;
1011 }
1012 }
1013
1014 gate_result_t gate_account_set_user_property(gate_account_user_t const* user, gate_string_t const* key, gate_property_t const* value)
1015 {
1016 gate_result_t ret = GATE_RESULT_FAILED;
1017 WCHAR system_name[GATE_ACCOUNTS_MAX_SYSTEM_NAME] = GATE_INIT_EMPTY;
1018 WCHAR const* ptr_system_name = NULL;
1019 WCHAR w_user_name[256] = GATE_INIT_EMPTY;
1020 gate_string_t prop_str_value = GATE_STRING_INIT_EMPTY;
1021 gate_bool_t prop_bool_value = false;
1022 WCHAR w_value[4096] = GATE_INIT_EMPTY;
1023 GATE_USER_INFO_2* ptr_user_info = NULL;
1024 DWORD net_status;
1025 DWORD param_error_index = 0;
1026
1027 do
1028 {
1029 if (!load_netapi() || !win32_netapi.NetUserGetInfo || !win32_netapi.NetUserSetInfo)
1030 {
1031 ret = GATE_RESULT_NOTSUPPORTED;
1032 break;
1033 }
1034
1035 ptr_system_name = gate_account_get_local_computer(system_name, sizeof(system_name) / sizeof(system_name[0]));
1036
1037 gate_str_utf8_2_utf16(user->name, gate_str_length(user->name), w_user_name, sizeof(w_user_name) / sizeof(w_user_name[0]));
1038 net_status = win32_netapi.NetUserGetInfo(ptr_system_name, w_user_name, 2, (LPBYTE*)&ptr_user_info);
1039 if (0 != net_status)
1040 {
1041 ret = GATE_RESULT_FAILED;
1042 break;
1043 }
1044
1045 ret = GATE_RESULT_INVALIDARG;
1046
1047 switch (gate_property_get_type(value))
1048 {
1049 case GATE_PROPERTY_TYPE_STRING:
1050 {
1051 ret = gate_property_get_string(value, &prop_str_value);
1052 GATE_BREAK_IF_FAILED(ret);
1053 gate_str_utf8_2_utf16(prop_str_value.str, prop_str_value.length, w_value, sizeof(w_value) / sizeof(w_value[0]));
1054
1055 if (gate_string_equals(key, &gate_account_user_key_comment)) { ptr_user_info->usri2_comment = w_value; }
1056 else if (gate_string_equals(key, &gate_account_user_key_full_name)) { ptr_user_info->usri2_full_name = w_value; }
1057 else if (gate_string_equals(key, &gate_account_user_key_home_dir)) { ptr_user_info->usri2_home_dir = w_value; }
1058 else if (gate_string_equals(key, &gate_account_user_key_script_path)) { ptr_user_info->usri2_script_path = w_value; }
1059 else { ret = GATE_RESULT_INVALIDARG; }
1060
1061 break;
1062 }
1063 case GATE_PROPERTY_TYPE_BOOL:
1064 {
1065 ret = gate_property_get_bool(value, &prop_bool_value);
1066 GATE_BREAK_IF_FAILED(ret);
1067
1068 if (gate_string_equals(key, &gate_account_user_key_script_enabled)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_SCRIPT, prop_bool_value); }
1069 else if (gate_string_equals(key, &gate_account_user_key_account_disabled)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_ACCOUNTDISABLE, prop_bool_value); }
1070 else if (gate_string_equals(key, &gate_account_user_key_lockout)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_LOCKOUT, prop_bool_value); }
1071 else if (gate_string_equals(key, &gate_account_user_key_no_password_expiration)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_DONT_EXPIRE_PASSWD, prop_bool_value); }
1072 else if (gate_string_equals(key, &gate_account_user_key_password_expired)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_PASSWORD_EXPIRED, prop_bool_value); }
1073 else if (gate_string_equals(key, &gate_account_user_key_cannot_change_password)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_PASSWD_CANT_CHANGE, prop_bool_value); }
1074 else if (gate_string_equals(key, &gate_account_user_key_password_not_required)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_PASSWD_NOTREQD, prop_bool_value); }
1075 else if (gate_string_equals(key, &gate_account_user_key_home_dir_required)) { gate_account_update_flag(&ptr_user_info->usri2_flags, UF_ACCOUNTDISABLE, prop_bool_value); }
1076 else { ret = GATE_RESULT_INVALIDARG; }
1077
1078 break;
1079 }
1080 default:
1081 {
1082 break;
1083 }
1084 }
1085 GATE_BREAK_IF_FAILED(ret);
1086
1087 net_status = win32_netapi.NetUserSetInfo(ptr_system_name, w_user_name, 2, (LPBYTE)ptr_user_info, &param_error_index);
1088 if (0 != net_status)
1089 {
1090 ret = GATE_RESULT_FAILED;
1091 break;
1092 }
1093
1094 ret = GATE_RESULT_OK;
1095 } while (0);
1096
1097 if (ptr_user_info != NULL)
1098 {
1099 win32_netapi.NetApiBufferFree(ptr_user_info);
1100 }
1101 gate_string_release(&prop_str_value);
1102 return ret;
1103 }
1104
1105
1106
1107 #endif /* GATE_SYSTEM_ACCOUNTS_WINLM */
1108
1109 #if defined(GATE_SYSTEM_ACCOUNTS_POSIX)
1110
1111 #include "gate/platforms.h"
1112
1113 21 static gate_result_t gate_account_build_user(uid_t uid, gate_account_user_t* user)
1114 {
1115 gate_result_t result;
1116 gate_posix_user_info_t user_info;
1117
1118 21 gate_mem_clear(&user_info, sizeof(user_info));
1119 21 gate_mem_clear(user, sizeof(gate_account_user_t));
1120
1121 21 user->short_id = (gate_uint64_t)uid;
1122 21 gate_str_print_uint(user->id, sizeof(user->id), uid, 0);
1123
1124 21 result = gate_posix_get_user_info(uid, &user_info);
1125
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (GATE_SUCCEEDED(result))
1126 {
1127 21 gate_str_print_text(user->name, sizeof(user->name), user_info.name, gate_str_length(user_info.name));
1128 21 gate_str_print_text(user->info, sizeof(user->info), user_info.gecos, gate_str_length(user_info.gecos));
1129 }
1130 21 return result;
1131 }
1132
1133 41 static gate_result_t gate_account_build_group(gid_t gid, gate_account_group_t* group)
1134 {
1135 gate_result_t result;
1136 gate_posix_group_info_t group_info;
1137 41 gate_mem_clear(&group_info, sizeof(group_info));
1138 41 gate_mem_clear(group, sizeof(gate_account_group_t));
1139
1140 41 group->short_id = (gate_uint64_t)gid;
1141 41 gate_str_print_uint(group->id, sizeof(group->id), gid, 0);
1142
1143 41 result = gate_posix_get_usergroup_info(gid, &group_info);
1144
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if (GATE_SUCCEEDED(result))
1145 {
1146 41 gate_str_print_text(group->name, sizeof(group->name), group_info.name, gate_str_length(group_info.name));
1147 }
1148 41 return result;
1149 }
1150
1151 1 gate_result_t gate_account_enum_users(gate_account_enum_users_callback_t callback, void* param)
1152 {
1153 1 gate_result_t ret = GATE_RESULT_FAILED;
1154 uid_t uids[1024];
1155 gate_size_t uids_received;
1156 gate_size_t index;
1157 gate_account_user_t user;
1158
1159 do
1160 {
1161 1 uids_received = gate_posix_enum_users(uids, sizeof(uids) / sizeof(uids[0]));
1162
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 for (index = 0; index != uids_received; ++index)
1163 {
1164 21 gate_account_build_user(uids[index], &user);
1165
1166
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
21 if (!callback(&user, param))
1167 {
1168 break;
1169 }
1170 }
1171 1 ret = GATE_RESULT_OK;
1172 } while (0);
1173
1174 1 return ret;
1175 }
1176 1 gate_result_t gate_account_enum_groups(gate_account_enum_groups_callback_t callback, void* param)
1177 {
1178 1 gate_result_t ret = GATE_RESULT_FAILED;
1179 gid_t gids[1024];
1180 gate_size_t gids_received;
1181 gate_size_t index;
1182 gate_account_group_t group;
1183
1184 do
1185 {
1186 1 gids_received = gate_posix_enum_groups(gids, sizeof(gids) / sizeof(gids[0]));
1187
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1 times.
42 for (index = 0; index != gids_received; ++index)
1188 {
1189 41 gate_account_build_group(gids[index], &group);
1190
1191
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 if (!callback(&group, param))
1192 {
1193 break;
1194 }
1195 }
1196 1 ret = GATE_RESULT_OK;
1197 } while (0);
1198
1199 1 return ret;
1200 }
1201 gate_result_t gate_account_enum_group_members(gate_account_group_t const* group, gate_account_enum_users_callback_t callback, void* param)
1202 {
1203 gate_result_t ret = GATE_RESULT_FAILED;
1204 gid_t gid = (gid_t)group->short_id;
1205 gate_posix_group_info_t group_info = GATE_INIT_EMPTY;
1206 gate_size_t index;
1207 gate_account_user_t user = GATE_INIT_EMPTY;
1208
1209 do
1210 {
1211 ret = gate_posix_get_usergroup_info(gid, &group_info);
1212 GATE_BREAK_IF_FAILED(ret);
1213
1214 for (index = 0; index < group_info.members_count; ++index)
1215 {
1216 gate_account_build_user(group_info.members[index], &user);
1217
1218 if (!callback(&user, param))
1219 {
1220 break;
1221 }
1222 }
1223 ret = GATE_RESULT_OK;
1224 } while (0);
1225
1226 return ret;
1227 }
1228 gate_result_t gate_account_enum_user_memberships(gate_account_user_t const* user, gate_account_enum_groups_callback_t callback, void* param)
1229 {
1230 gate_result_t ret = GATE_RESULT_FAILED;
1231 uid_t uid = (uid_t)user->short_id;
1232 gate_posix_user_info_t user_info = GATE_INIT_EMPTY;
1233 gate_account_group_t group = GATE_INIT_EMPTY;
1234
1235 do
1236 {
1237 ret = gate_posix_get_user_info(uid, &user_info);
1238 GATE_BREAK_IF_FAILED(ret);
1239
1240 gate_account_build_group(user_info.gid, &group);
1241
1242 callback(&group, param);
1243 ret = GATE_RESULT_OK;
1244
1245 } while (0);
1246 return ret;
1247 }
1248 gate_result_t gate_account_get_user(gate_string_t const* user_id, gate_account_user_t* user)
1249 {
1250 gate_result_t ret = GATE_RESULT_FAILED;
1251 gate_uint64_t ui64 = (gate_uint64_t)-1;
1252 do
1253 {
1254 gate_str_parse_uint64(user_id->str, user_id->length, &ui64);
1255
1256 ret = gate_account_build_user((uid_t)ui64, user);
1257 } while (0);
1258 return ret;
1259 }
1260 gate_result_t gate_account_resolve_user(gate_string_t const* user_name, gate_account_user_t* user)
1261 {
1262 gate_result_t ret = GATE_RESULT_FAILED;
1263 char user_str[128] = GATE_INIT_EMPTY;
1264 gate_posix_user_info_t user_info;
1265
1266 do
1267 {
1268 gate_string_to_buffer(user_name, user_str, sizeof(user_str));
1269
1270 ret = gate_posix_resolve_user_info(user_str, &user_info);
1271 GATE_BREAK_IF_FAILED(ret);
1272
1273 gate_account_build_user(user_info.uid, user);
1274 } while (0);
1275 return ret;
1276 }
1277 gate_result_t gate_account_get_group(gate_string_t const* group_id, gate_account_group_t* group)
1278 {
1279 gate_result_t ret = GATE_RESULT_FAILED;
1280 gate_uint64_t ui64 = (gate_uint64_t)-1;
1281 do
1282 {
1283 gate_str_parse_uint64(group_id->str, group_id->length, &ui64);
1284
1285 ret = gate_account_build_group((uid_t)ui64, group);
1286 } while (0);
1287 return ret;
1288 }
1289 gate_result_t gate_account_resolve_group(gate_string_t const* group_name, gate_account_group_t* group)
1290 {
1291 gate_result_t ret = GATE_RESULT_FAILED;
1292 char group_str[128] = GATE_INIT_EMPTY;
1293 gate_posix_group_info_t group_info;
1294
1295 do
1296 {
1297 gate_string_to_buffer(group_name, group_str, sizeof(group_str));
1298
1299 ret = gate_posix_resolve_usergroup_info(group_str, &group_info);
1300 GATE_BREAK_IF_FAILED(ret);
1301
1302 gate_account_build_group(group_info.gid, group);
1303 } while (0);
1304 return ret;
1305 }
1306 gate_result_t gate_account_create_user(gate_string_t const* user_name, gate_string_t const* password)
1307 {
1308 return GATE_RESULT_NOTIMPLEMENTED;
1309 }
1310 gate_result_t gate_account_delete_user(gate_account_user_t const* user)
1311 {
1312 return GATE_RESULT_NOTIMPLEMENTED;
1313 }
1314 gate_result_t gate_account_create_group(gate_string_t const* group_name)
1315 {
1316 return GATE_RESULT_NOTIMPLEMENTED;
1317 }
1318 gate_result_t gate_account_delete_group(gate_account_group_t const* group)
1319 {
1320 return GATE_RESULT_NOTIMPLEMENTED;
1321 }
1322 gate_result_t gate_account_add_user_to_group(gate_account_user_t const* user, gate_account_group_t const* group)
1323 {
1324 return GATE_RESULT_NOTIMPLEMENTED;
1325 }
1326 gate_result_t gate_account_remove_user_from_group(gate_account_user_t const* user, gate_account_group_t const* group)
1327 {
1328 return GATE_RESULT_NOTIMPLEMENTED;
1329 }
1330 gate_result_t gate_account_get_user_properties(gate_account_user_t const* user, gate_property_t* properties)
1331 {
1332 return GATE_RESULT_NOTIMPLEMENTED;
1333 }
1334 gate_result_t gate_account_set_user_property(gate_account_user_t const* user, gate_string_t const* key, gate_property_t const* value)
1335 {
1336 return GATE_RESULT_NOTIMPLEMENTED;
1337 }
1338
1339
1340
1341 #endif /* GATE_SYSTEM_ACCOUNTS_POSIX */
1342
1343
1344 #if defined(GATE_SYSTEM_ACCOUNTS_NO_IMPL)
1345
1346 gate_result_t gate_account_enum_users(gate_account_enum_users_callback_t callback, void* param)
1347 {
1348 return GATE_RESULT_NOTIMPLEMENTED;
1349 }
1350 gate_result_t gate_account_enum_groups(gate_account_enum_groups_callback_t callback, void* param)
1351 {
1352 return GATE_RESULT_NOTIMPLEMENTED;
1353 }
1354 gate_result_t gate_account_enum_group_members(gate_account_group_t const* group, gate_account_enum_users_callback_t callback, void* param)
1355 {
1356 (void)group;
1357 (void)callback;
1358 (void)param;
1359 return GATE_RESULT_NOTIMPLEMENTED;
1360 }
1361 gate_result_t gate_account_enum_user_memberships(gate_account_group_t const* user, gate_account_enum_groups_callback_t callback, void* param)
1362 {
1363 (void)user;
1364 (void)callback;
1365 (void)param;
1366 return GATE_RESULT_NOTIMPLEMENTED;
1367 }
1368 gate_result_t gate_account_get_user(gate_string_t const* user_id, gate_account_user_t* user)
1369 {
1370 (void)user_id;
1371 (void)user;
1372 return GATE_RESULT_NOTIMPLEMENTED;
1373 }
1374 gate_result_t gate_account_resolve_user(gate_string_t const* user_name, gate_account_user_t* user)
1375 {
1376 (void)user_name;
1377 (void)user;
1378 return GATE_RESULT_NOTIMPLEMENTED;
1379 }
1380 gate_result_t gate_account_get_group(gate_string_t const* group_id, gate_account_group_t* group)
1381 {
1382 (void)group_id;
1383 (void)group;
1384 return GATE_RESULT_NOTIMPLEMENTED;
1385 }
1386 gate_result_t gate_account_resolve_group(gate_string_t const* group_name, gate_account_group_t* group)
1387 {
1388 (void)group_name;
1389 (void)group;
1390 return GATE_RESULT_NOTIMPLEMENTED;
1391 }
1392 gate_result_t gate_account_create_user(gate_string_t const* user_name, char const* password)
1393 {
1394 (void)user_name;
1395 (void)password;
1396 return GATE_RESULT_NOTIMPLEMENTED;
1397 }
1398 gate_result_t gate_account_delete_user(gate_account_user_t const* user)
1399 {
1400 (void)user;
1401 return GATE_RESULT_NOTIMPLEMENTED;
1402 }
1403 gate_result_t gate_account_create_group(gate_string_t const* group_name)
1404 {
1405 (void)group_name;
1406 return GATE_RESULT_NOTIMPLEMENTED;
1407 }
1408 gate_result_t gate_account_delete_group(gate_account_group_t const* group)
1409 {
1410 (void)group;
1411 return GATE_RESULT_NOTIMPLEMENTED;
1412 }
1413
1414 gate_result_t gate_account_add_user_to_group(gate_account_user_t const* user, gate_account_group_t const* group)
1415 {
1416 (void)user;
1417 (void)group;
1418 return GATE_RESULT_NOTIMPLEMENTED;
1419 }
1420 gate_result_t gate_account_remove_user_from_group(gate_account_user_t const* user, gate_account_group_t const* group)
1421 {
1422 (void)user;
1423 (void)group;
1424 return GATE_RESULT_NOTIMPLEMENTED;
1425 }
1426 gate_result_t gate_account_get_user_properties(gate_account_user_t const* user, gate_property_t* properties)
1427 {
1428 (void)user;
1429 (void)properties;
1430 return GATE_RESULT_NOTIMPLEMENTED;
1431 }
1432 gate_result_t gate_account_set_user_property(gate_account_user_t const* user, gate_string_t const* key, gate_property_t const* value);
1433 {
1434 (void)user;
1435 (void)key;
1436 (void)value;
1437 return GATE_RESULT_NOTIMPLEMENTED;
1438 }
1439
1440 #endif /* GATE_SYSTEM_ACCOUNTS_POSIX */
1441
1442
1443 #ifdef GATE_SYSTEM_ACCOUNTS_NOIMPL
1444
1445 gate_result_t gate_account_enum_users(gate_account_enum_users_callback_t callback, void* param)
1446 {
1447 (void)callback;
1448 (void)param;
1449 return GATE_RESULT_NOTIMPLEMENTED;
1450 }
1451 gate_result_t gate_account_enum_groups(gate_account_enum_groups_callback_t callback, void* param)
1452 {
1453 (void)callback;
1454 (void)param;
1455 return GATE_RESULT_NOTIMPLEMENTED;
1456 }
1457 gate_result_t gate_account_enum_group_members(gate_account_group_t const* group, gate_account_enum_users_callback_t callback, void* param)
1458 {
1459 (void)group;
1460 (void)callback;
1461 (void)param;
1462 return GATE_RESULT_NOTIMPLEMENTED;
1463 }
1464 gate_result_t gate_account_enum_user_memberships(gate_account_user_t const* user, gate_account_enum_groups_callback_t callback, void* param)
1465 {
1466 (void)user;
1467 (void)callback;
1468 (void)param;
1469 return GATE_RESULT_NOTIMPLEMENTED;
1470 }
1471 gate_result_t gate_account_get_user(gate_string_t const* user_id, gate_account_user_t* user)
1472 {
1473 (void)user_id;
1474 (void)user;
1475 return GATE_RESULT_NOTIMPLEMENTED;
1476 }
1477 gate_result_t gate_account_resolve_user(gate_string_t const* user_name, gate_account_user_t* user)
1478 {
1479 (void)user_name;
1480 (void)user;
1481 return GATE_RESULT_NOTIMPLEMENTED;
1482 }
1483 gate_result_t gate_account_get_group(gate_string_t const* group_id, gate_account_group_t* group)
1484 {
1485 (void)group_id;
1486 (void)group;
1487 return GATE_RESULT_NOTIMPLEMENTED;
1488 }
1489 gate_result_t gate_account_resolve_group(gate_string_t const* group_name, gate_account_group_t* group)
1490 {
1491 (void)group_name;
1492 (void)group;
1493 return GATE_RESULT_NOTIMPLEMENTED;
1494 }
1495 gate_result_t gate_account_create_user(gate_string_t const* user_name, gate_string_t const* password)
1496 {
1497 (void)user_name;
1498 (void)password;
1499 return GATE_RESULT_NOTIMPLEMENTED;
1500 }
1501 gate_result_t gate_account_delete_user(gate_account_user_t const* user)
1502 {
1503 (void)user;
1504 return GATE_RESULT_NOTIMPLEMENTED;
1505 }
1506 gate_result_t gate_account_create_group(gate_string_t const* group_name)
1507 {
1508 (void)group_name;
1509 return GATE_RESULT_NOTIMPLEMENTED;
1510 }
1511 gate_result_t gate_account_delete_group(gate_account_group_t const* group)
1512 {
1513 (void)group;
1514 return GATE_RESULT_NOTIMPLEMENTED;
1515 }
1516 gate_result_t gate_account_add_user_to_group(gate_account_user_t const* user, gate_account_group_t const* group)
1517 {
1518 (void)user;
1519 (void)group;
1520 return GATE_RESULT_NOTIMPLEMENTED;
1521 }
1522 gate_result_t gate_account_remove_user_from_group(gate_account_user_t const* user, gate_account_group_t const* group)
1523 {
1524 (void)user;
1525 (void)group;
1526 return GATE_RESULT_NOTIMPLEMENTED;
1527 }
1528 gate_result_t gate_account_get_user_properties(gate_account_user_t const* user, gate_property_t* properties)
1529 {
1530 (void)user;
1531 (void)properties;
1532 return GATE_RESULT_NOTIMPLEMENTED;
1533 }
1534 gate_result_t gate_account_set_user_property(gate_account_user_t const* user, gate_string_t const* key, gate_property_t const* value)
1535 {
1536 (void)user;
1537 (void)key;
1538 (void)value;
1539 return GATE_RESULT_NOTIMPLEMENTED;
1540 }
1541
1542
1543 #endif /* GATE_SYSTEM_ACCOUNTS_NOIMPL */
1544
1545