summaryrefslogtreecommitdiff
path: root/support/dktools/dk4user.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4user.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk4user.ctr')
-rw-r--r--support/dktools/dk4user.ctr470
1 files changed, 470 insertions, 0 deletions
diff --git a/support/dktools/dk4user.ctr b/support/dktools/dk4user.ctr
new file mode 100644
index 0000000000..4d9d89afe4
--- /dev/null
+++ b/support/dktools/dk4user.ctr
@@ -0,0 +1,470 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2015-xxxx
+license = bsd
+
+
+
+%% header
+
+/** @file
+ Get information about user
+ (login name and home directory).
+*/
+
+#ifndef DK4CONF_H_INCLUDED
+#include "dk4conf.h"
+#endif
+
+#ifndef DK4TYPES_H_INCLUDED
+#include "dk4types.h"
+#endif
+
+#ifndef DK4ERROR_H_INCLUDED
+#include "dk4error.h"
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get users login name.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Not used.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name was not found,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the buffer is too small for the result.
+*/
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+/** Get users home directory.
+ @param pdst Pointer to destination buffer.
+ @param szdst Size of destination buffer (number of characters).
+ @param eff Flag: Retrieve information about effective user.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+
+ CRT on Windows: Optional.
+
+ Error codes:
+ - DK4_E_INVALID_ARGUMENTS<br>
+ if pdst is NULL or szdst is 0,
+ - DK4_E_NOT_FOUND<br>
+ if the login name, the user entry or the home
+ directory was not found,
+ - DK4_E_MEMORY<br>
+ if an internal memory allocation failed,
+ - DK4_E_SYNTAX<br>
+ if the retrieved registry entry on
+ Windows is not a string,
+ - DK4_E_BUFFER_TOO_SMALL<br>
+ if the pdst buffer or one of the internal buffers
+ is too small for the result.
+*/
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+%% module
+
+
+#include "dk4user.h"
+#include "dk4str8.h"
+#include "dk4strw.h"
+#include "dk4strd.h"
+#include "dk4wregw.h"
+#include "dk4wregc.h"
+#include "dk4mem.h"
+#include "dk4error.h"
+#include "dk4masz.h"
+#include "dk4mpl.h"
+
+
+#if DK4_ON_WINDOWS
+#ifndef WINDOWS_H_INCLUDED
+#include <windows.h>
+#define WINDOWS_H_INCLUDED 1
+#endif
+#ifndef LM_H_INCLUDED
+#include <lm.h>
+#define LM_H_INCLUDED 1
+#endif
+#ifndef SDDL_H_INCLUDED
+#include <sddl.h>
+#define SDDL_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_SYS_TYPES_H
+#ifndef SYS_TYPES_H_INCLUDED
+#include <sys/types.h>
+#define SYS_TYPES_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_UNISTD_H
+#ifndef UNISTD_H_INCLUDED
+#include <unistd.h>
+#define UNISTD_H_INCLUDED 1
+#endif
+#endif
+
+#if DK4_HAVE_PWD_H
+#ifndef PWD_H_INCLUDED
+#include <pwd.h>
+#define PWD_H_INCLUDED 1
+#endif
+#endif
+
+
+
+$!trace-include
+
+
+
+#if DK4_ON_WINDOWS
+static const wchar_t * const dk4user_kw[] = {
+$!string-table prefix=L
+#
+# 0 ... 2 Registry key name and value name for profile dir
+#
+SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList
+\\
+ProfileImagePath
+#
+# 3 4 5 6
+#
+LOGONSERVER
+USERPROFILE
+HOMEDRIVE
+HOMEPATH
+$!end
+};
+#endif
+
+int
+dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+ DWORD sz;
+ int back = 0;
+ $? "+ dk4user_get_logname (Windows)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ sz = (DWORD)szdst;
+#if DK4_CHAR_SIZE > 1
+ if(GetUserNameW(pdst, &sz))
+#else
+ if(GetUserNameA(pdst, &sz))
+#endif
+ {
+ if (sz < szdst) {
+ pdst[sz] = dkT('\0');
+ back = 1;
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
+ }
+ }
+ else
+ {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_logname (Windows) %d", back
+ return back;
+#else
+#if DK4_CHAR_SIZE > 1
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+#else
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+ $? "+ dk4user_get_logname (non-Windows, char)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_name) {
+ if (0 != dk4str_cpy_s(pdst, szdst, pwent->pw_name, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_logname (non-Windows, char) %d", back
+ return back;
+#endif
+#endif
+}
+
+
+
+#if DK4_ON_WINDOWS
+
+
+
+/** Obtain home directory information using one logon server.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param lsn Logon server name, may be NULL.
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_ls_homedir(
+ wchar_t *pdst, size_t szdst, const wchar_t *lsn, dk4_er_t *erp
+)
+{
+ wchar_t b1[DK4_MAX_PATH+16]; /* Buffer RegQueryValue() */
+ wchar_t b2[DK4_MAX_PATH+16]; /* Buffer Expand...() */
+ wchar_t logname[256]; /* Login name */
+ dk4_er_t er; /* Error report */
+ USER_INFO_4 *pbuf4 = NULL; /* User information */
+ wchar_t *pStringSid = NULL; /* String SID */
+ wchar_t *keyname = NULL; /* Registry key name */
+ void *wrkey = NULL; /* Registry key */
+ DWORD szlog = DK4_SIZEOF(logname,wchar_t);
+ size_t sz = 0; /* Key name length */
+ int back = 0; /* Result */
+ NET_API_STATUS nStatus = 0; /* Network op result */
+ $? "+ dk4user_get_i_ls_homedir lsn=\"%!ws\"", TR_LSTR(lsn)
+ dk4error_init(&er);
+ if (GetUserNameW(logname, &szlog)) { $? ". user name found"
+ if (DK4_SIZEOF(logname,wchar_t) >= szlog) { $? ". name size ok"
+ logname[szlog] = L'\0';
+ nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4));
+ if ((NERR_Success == nStatus) && (NULL != pbuf4)) { $? ". user info"
+ if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) {
+ $? ". sid"
+ sz = dk4ma_size_t_add(
+ dk4ma_size_t_add(
+ 1,
+ dk4strw_len(dk4user_kw[0]),
+ &er
+ ),
+ dk4ma_size_t_add(
+ dk4strw_len(dk4user_kw[1]),
+ dk4strw_len(pStringSid),
+ &er
+ ),
+ &er
+ );
+ if (DK4_E_NONE == er.ec) { $? ". size calc 1 ok"
+ (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er);
+ if (DK4_E_NONE == er.ec) { $? ". size calc 2 ok"
+ keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er);
+ if (NULL != keyname) { $? ". calloc ok"
+ (void)dk4strw_cpy_s(keyname, sz, dk4user_kw[0], NULL);
+ (void)dk4strw_cat_s(keyname, sz, dk4user_kw[1], NULL);
+ (void)dk4strw_cat_s(keyname, sz, pStringSid, NULL);
+ wrkey = dk4wreg_open_key_wc(DK4_WREGKEY_HKLM, keyname, 0, &er);
+ if (NULL != wrkey) { $? ". key opened"
+ back = dk4wreg_get_expanded_string_wc(
+ wrkey,
+ dk4user_kw[2],
+ pdst, szdst,
+ b1, DK4_SIZEOF(b1,wchar_t),
+ b2, (DK4_SIZEOF(b2,wchar_t)-2),
+ &er
+ ); $? ". back = %d", back
+ dk4wreg_close_key(wrkey);
+ } else { $? "! registry key"
+ /* ERROR: Failed to open key (reported) */
+ }
+ dk4mem_free(keyname);
+ } else { $? "! memory"
+ /* ERROR: Memory (reported) */
+ }
+ } else { $? "! size calc overflow"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else { $? "! size calc overflow"
+ /* ERROR: Overflow in size calculation (reported) */
+ }
+ } else { $? "! failed to convert sid"
+ /* ERROR: Failed to convert SID */
+ dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND);
+ }
+ if (NULL != pStringSid) {
+ LocalFree(pStringSid);
+ }
+ } else { $? "! failed to obtain info"
+ /* ERROR: No user info */
+ }
+ if (NULL != pbuf4) {
+ NetApiBufferFree(pbuf4);
+ }
+ } else { $? "! user name too long"
+ /* ERROR: User name too long */
+ dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL);
+ }
+ } else { $? "! user name not found"
+ /* ERROR: User name not found */
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &er);
+ }
+ $? "- dk4user_get_i_ls_homedir %d", back
+ return back;
+}
+
+
+
+/** Find Windows home directory.
+ @param pdst Destination buffer pointer.
+ @param szdst Destination buffer size (number of wchar_t).
+ @param erp Error report, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk4user_get_i_homedir(wchar_t *pdst, size_t szdst, dk4_er_t *erp)
+{
+ dk4_er_t myerp;
+ wchar_t *lsn = NULL;
+ wchar_t *hop = NULL;
+ int back = 0;
+ $? "+ dk4user_get_i_homedir"
+ dk4error_init(&myerp);
+ back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp);
+ $? ". back = %d", back
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[4]); $? ". userprofile"
+ if (NULL != lsn) {
+ back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp);
+ $? ". back = %d", back
+ } else { $? "! userprofile"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[5]);
+ hop = _wgetenv(dk4user_kw[6]);
+ if ((NULL != lsn) && (NULL != hop)) { $? ". drive / path"
+ if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) {
+ back = dk4strw_cat_s(pdst, szdst, hop, &myerp);
+ $? ". back = %d", back
+ } else { $? "! too long"
+ }
+ } else { $? "! drive / path"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ lsn = _wgetenv(dk4user_kw[3]);
+ if (NULL != lsn) { $? ". env ok"
+ back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp);
+ $? ". back = %d", back
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt"
+ if (NULL != lsn) { $? ". lsn"
+ if (L'\\' == lsn[0]) {
+ if (L'\\' == lsn[1]) {
+ back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp);
+ $? ". back = %d", back
+ } else { $? "! lsn[1]"
+ }
+ } else { $? "! lsn[0]"
+ }
+ } else { $? "! lsn"
+ }
+ }
+ if ((0 == back) && (DK4_E_NONE == myerp.ec)) {
+ dk4error_set_simple_error_code(&myerp, DK4_E_NOT_FOUND);
+ }
+ if (0 == back) {
+ dk4error_copy(erp, &myerp);
+ } $? "- dk4user_get_i_homedir %d", back
+ return back;
+}
+
+#endif
+
+
+int
+dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp)
+{
+#if DK4_ON_WINDOWS
+/* +++++ Windows +++++ */
+#if DK4_CHAR_SIZE == 1
+ wchar_t homew[DK4_MAX_PATH];
+#endif
+ int back = 0;
+ $? "+ dk4user_get_homedir"
+ if ((NULL != pdst) && (0 < szdst)) { $? ". arguments"
+ *pdst = dkT('\0');
+#if DK4_CHAR_SIZE > 1
+ $? ". wchar_t"
+ back = dk4user_get_i_homedir(pdst, szdst, erp);
+#else
+ $? ". char"
+ if (0 != dk4user_get_i_homedir(homew, DK4_SIZEOF(homew,wchar_t), erp)) {
+ back = dk4recode_utf16_to_ansi(pdst, szdst, homew, erp);
+ }
+#endif
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_homedir %d", back
+ return back;
+/* ----- Windows ----- */
+#else
+/* +++++ non-Windows +++++ */
+#if DK4_CHAR_SIZE > 1
+/* +++++ non-Windows wchar_t +++++ */
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
+ return 0;
+/* ----- non-Windows wchar_t ----- */
+#else
+/* +++++ non-Windows char +++++ */
+ struct passwd *pwent;
+ uid_t uid;
+ int back = 0;
+ $? "+ dk4user_get_homedir (non-windows, char)"
+ if ((NULL != pdst) && (0 < szdst)) {
+ if (0 != eff) { uid = geteuid(); } else { uid = getuid(); }
+ pwent = getpwuid(uid);
+ if (NULL != pwent) {
+ if (NULL != pwent->pw_dir) {
+ if (0 != dk4str8_cpy_s(pdst, szdst, pwent->pw_dir, erp)) {
+ back = 1;
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
+ }
+ } else {
+ dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
+ } $? "- dk4user_get_homedir (non-windows, char) %d", back
+ return back;
+/* ----- non-Windows char ----- */
+#endif
+/* ----- non-Windows ----- */
+#endif
+}
+