Add portable path tokens
Add USERCONFIG, COMMONCONFIG, LIBDIR, BINDIR, LIBEXEC, SBINDIR tokens.
This commit is contained in:

committed by
Love Hornquist Astrand

parent
93445a8133
commit
6073ca9a28
@@ -33,7 +33,7 @@
|
|||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
||||||
#define PTYPE int
|
typedef int PTYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand a %{TEMP} token
|
* Expand a %{TEMP} token
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
* the returned path may or may not exist.
|
* the returned path may or may not exist.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_expand_temp_folder(krb5_context context, PTYPE param, char ** ret)
|
_expand_temp_folder(krb5_context context, PTYPE param, const char * postfix, char ** ret)
|
||||||
{
|
{
|
||||||
TCHAR tpath[MAX_PATH];
|
TCHAR tpath[MAX_PATH];
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -56,7 +56,7 @@ _expand_temp_folder(krb5_context context, PTYPE param, char ** ret)
|
|||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "Failed to get temporary path (GLE=%d)",
|
krb5_set_error_string(context, "Failed to get temporary path (GLE=%d)",
|
||||||
GetLastError());
|
GetLastError());
|
||||||
return 1;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(tpath);
|
len = strlen(tpath);
|
||||||
@@ -69,12 +69,57 @@ _expand_temp_folder(krb5_context context, PTYPE param, char ** ret)
|
|||||||
if (*ret == NULL) {
|
if (*ret == NULL) {
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "strdup - Out of memory");
|
krb5_set_error_string(context, "strdup - Out of memory");
|
||||||
return 1;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern HINSTANCE _krb5_hInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand a %{BINDIR} token
|
||||||
|
*
|
||||||
|
* This is also used to expand a few other tokens on Windows, since
|
||||||
|
* most of the executable binaries end up in the same directory. The
|
||||||
|
* "bin" directory is considered to be the directory in which the
|
||||||
|
* krb5.dll is located.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
_expand_bin_dir(krb5_context context, PTYPE param, const char * postfix, char ** ret)
|
||||||
|
{
|
||||||
|
TCHAR path[MAX_PATH];
|
||||||
|
TCHAR *lastSlash;
|
||||||
|
DWORD nc;
|
||||||
|
|
||||||
|
nc = GetModuleFileName(_krb5_hInstance, path, sizeof(path)/sizeof(path[0]));
|
||||||
|
if (nc == 0 ||
|
||||||
|
nc == sizeof(path)/sizeof(path[0])) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSlash = strrchr(path, '\\');
|
||||||
|
if (lastSlash != NULL) {
|
||||||
|
TCHAR *fslash = strrchr(lastSlash, '/');
|
||||||
|
|
||||||
|
if (fslash != NULL)
|
||||||
|
lastSlash = fslash;
|
||||||
|
|
||||||
|
*lastSlash = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (postfix) {
|
||||||
|
if (strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0]))
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = strdup(path);
|
||||||
|
if (*ret == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand a %{USERID} token
|
* Expand a %{USERID} token
|
||||||
*
|
*
|
||||||
@@ -91,9 +136,9 @@ _expand_temp_folder(krb5_context context, PTYPE param, char ** ret)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_expand_userid(krb5_context context, PTYPE param, char ** ret)
|
_expand_userid(krb5_context context, PTYPE param, const char * postfix, char ** ret)
|
||||||
{
|
{
|
||||||
int rv = 1;
|
int rv = EINVAL;
|
||||||
HANDLE hThread = NULL;
|
HANDLE hThread = NULL;
|
||||||
HANDLE hToken = NULL;
|
HANDLE hToken = NULL;
|
||||||
PTOKEN_OWNER pOwner = NULL;
|
PTOKEN_OWNER pOwner = NULL;
|
||||||
@@ -181,21 +226,34 @@ _expand_userid(krb5_context context, PTYPE param, char ** ret)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand a %{null} token
|
||||||
|
*
|
||||||
|
* The expansion of a %{null} token is always the empty string.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
_expand_null(krb5_context context, PTYPE param, char ** ret)
|
_expand_null(krb5_context context, PTYPE param, const char * postfix, char ** ret)
|
||||||
{
|
{
|
||||||
*ret = strdup("");
|
*ret = strdup("");
|
||||||
if (*ret == NULL) {
|
if (*ret == NULL) {
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "Out of memory");
|
krb5_set_error_string(context, "Out of memory");
|
||||||
return 1;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand a folder identified by a CSIDL
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* @param[in] folder A CSIDL value identifying the folder to be
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
_expand_csidl(krb5_context context, PTYPE folder, char ** ret)
|
_expand_csidl(krb5_context context, PTYPE folder, const char * postfix, char ** ret)
|
||||||
{
|
{
|
||||||
TCHAR path[MAX_PATH];
|
TCHAR path[MAX_PATH];
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -211,11 +269,16 @@ _expand_csidl(krb5_context context, PTYPE folder, char ** ret)
|
|||||||
if (len > 0 && path[len - 1] == '\\')
|
if (len > 0 && path[len - 1] == '\\')
|
||||||
path[len - 1] = '\0';
|
path[len - 1] = '\0';
|
||||||
|
|
||||||
|
if (postfix &&
|
||||||
|
strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
*ret = strdup(path);
|
*ret = strdup(path);
|
||||||
if (*ret == NULL) {
|
if (*ret == NULL) {
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "Out of memory");
|
krb5_set_error_string(context, "Out of memory");
|
||||||
return 1;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -227,14 +290,18 @@ static const struct token {
|
|||||||
#define FTYPE_SPECIAL 1
|
#define FTYPE_SPECIAL 1
|
||||||
|
|
||||||
PTYPE param;
|
PTYPE param;
|
||||||
|
const char * postfix;
|
||||||
|
|
||||||
int (*exp_func)(krb5_context, PTYPE, char **);
|
int (*exp_func)(krb5_context, PTYPE, const char *, char **);
|
||||||
|
|
||||||
#define CSIDL(C) FTYPE_CSIDL, C, _expand_csidl
|
#define CSIDLP(C,P) FTYPE_CSIDL, C, P, _expand_csidl
|
||||||
|
#define CSIDL(C) CSIDLP(C, NULL)
|
||||||
|
|
||||||
#define SPECIAL(f) FTYPE_SPECIAL, 0, f
|
#define SPECIALP(f, P) FTYPE_SPECIAL, 0, P, f
|
||||||
|
#define SPECIAL(f) SPECIALP(f, NULL)
|
||||||
|
|
||||||
} tokens[] = {
|
} tokens[] = {
|
||||||
|
/* Windows only -- */
|
||||||
{"APPDATA", CSIDL(CSIDL_APPDATA)},
|
{"APPDATA", CSIDL(CSIDL_APPDATA)},
|
||||||
/* Roaming application data (for current user) */
|
/* Roaming application data (for current user) */
|
||||||
|
|
||||||
@@ -249,6 +316,34 @@ static const struct token {
|
|||||||
|
|
||||||
{"WINDOWS", CSIDL(CSIDL_WINDOWS)},
|
{"WINDOWS", CSIDL(CSIDL_WINDOWS)},
|
||||||
/* Windows folder */
|
/* Windows folder */
|
||||||
|
/* -- end Windows only */
|
||||||
|
|
||||||
|
{"USERCONFIG", CSIDLP(CSIDL_APPDATA, "\\" PACKAGE)},
|
||||||
|
/* Per user Heimdal configuration file path */
|
||||||
|
|
||||||
|
{"COMMONCONFIG", CSIDLP(CSIDL_COMMON_APPDATA, "\\" PACKAGE)},
|
||||||
|
/* Common Heimdal configuration file path */
|
||||||
|
|
||||||
|
{"LIBDIR", SPECIAL(_expand_bin_dir)},
|
||||||
|
/* Expands to the "lib" directory. On
|
||||||
|
Windows this is treated the same as
|
||||||
|
the "bin" directory. */
|
||||||
|
|
||||||
|
{"BINDIR", SPECIAL(_expand_bin_dir)},
|
||||||
|
/* Expands to the "bin" directory. On
|
||||||
|
Windows this is treated the same as
|
||||||
|
the "bin" directory. */
|
||||||
|
|
||||||
|
{"LIBEXEC", SPECIAL(_expand_bin_dir)},
|
||||||
|
/* Expands to the "libexec"
|
||||||
|
directory. On Windows, this is
|
||||||
|
treated the same as the "bin"
|
||||||
|
directory. */
|
||||||
|
|
||||||
|
{"SBINDIR", SPECIAL(_expand_bin_dir)},
|
||||||
|
/* Expands to the "sbin" directory.
|
||||||
|
On Windows, this is treated the
|
||||||
|
same as the "bin" directory. */
|
||||||
|
|
||||||
{"TEMP", SPECIAL(_expand_temp_folder)},
|
{"TEMP", SPECIAL(_expand_temp_folder)},
|
||||||
/* Temporary files folder */
|
/* Temporary files folder */
|
||||||
@@ -273,20 +368,32 @@ _expand_token(krb5_context context, const char * token, const char * token_end,
|
|||||||
|
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
|
|
||||||
if (token[0] != '%' || token[1] != '{' || token_end[0] != '}') {
|
if (token[0] != '%' || token[1] != '{' || token_end[0] != '}' ||
|
||||||
|
token_end - token <= 2) {
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "Invalid token.");
|
krb5_set_error_string(context, "Invalid token.");
|
||||||
return 1;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < sizeof(tokens)/sizeof(tokens[0]); i++) {
|
for (i=0; i < sizeof(tokens)/sizeof(tokens[0]); i++) {
|
||||||
if (!strncmp(token+2, tokens[i].tok, (token_end - token) - 2))
|
if (!strncmp(token+2, tokens[i].tok, (token_end - token) - 2))
|
||||||
return tokens[i].exp_func(context, tokens[i].param, ret);
|
return tokens[i].exp_func(context, tokens[i].param, tokens[i].postfix, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "Invalid token.");
|
krb5_set_error_string(context, "Invalid token.");
|
||||||
return 1;
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||||
|
_krb5_free_path(krb5_context context,
|
||||||
|
char * path)
|
||||||
|
{
|
||||||
|
if (path == NULL)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
free(path);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||||
@@ -322,14 +429,14 @@ _krb5_expand_path_tokens(krb5_context context,
|
|||||||
*ppath_out = NULL;
|
*ppath_out = NULL;
|
||||||
if (context)
|
if (context)
|
||||||
krb5_set_error_string(context, "variable missing }");
|
krb5_set_error_string(context, "variable missing }");
|
||||||
return KRB5_CONFIG_BADFORMAT;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_expand_token(context, tok_begin, tok_end, &append)) {
|
if (_expand_token(context, tok_begin, tok_end, &append)) {
|
||||||
if (*ppath_out)
|
if (*ppath_out)
|
||||||
free(*ppath_out);
|
free(*ppath_out);
|
||||||
*ppath_out = NULL;
|
*ppath_out = NULL;
|
||||||
return KRB5_CONFIG_BADFORMAT;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_left = tok_end + 1;
|
path_left = tok_end + 1;
|
||||||
|
Reference in New Issue
Block a user