Read configuration plist on macs
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@@ -35,6 +37,10 @@
|
|||||||
|
|
||||||
#include "krb5_locl.h"
|
#include "krb5_locl.h"
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Gaah! I want a portable funopen */
|
/* Gaah! I want a portable funopen */
|
||||||
struct fileptr {
|
struct fileptr {
|
||||||
const char *s;
|
const char *s;
|
||||||
@@ -233,6 +239,99 @@ parse_binding(struct fileptr *f, unsigned *lineno, char *p,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static char *
|
||||||
|
cfstring2cstring(CFStringRef string)
|
||||||
|
{
|
||||||
|
CFIndex len;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = (char *) CFStringGetCStringPtr(string, kCFStringEncodingUTF8);
|
||||||
|
if (str)
|
||||||
|
return strdup(str);
|
||||||
|
|
||||||
|
len = CFStringGetLength(string);
|
||||||
|
len = 1 + CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8);
|
||||||
|
str = malloc(len);
|
||||||
|
if (str == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!CFStringGetCString (string, str, len, kCFStringEncodingUTF8)) {
|
||||||
|
free (str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
convert_content(const void *key, const void *value, void *context)
|
||||||
|
{
|
||||||
|
krb5_config_section *tmp, **parent = context;
|
||||||
|
char *k, *v;
|
||||||
|
|
||||||
|
if (CFGetTypeID(key) != CFStringGetTypeID())
|
||||||
|
return;
|
||||||
|
|
||||||
|
k = cfstring2cstring(key);
|
||||||
|
if (k == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (CFGetTypeID(value) == CFStringGetTypeID()) {
|
||||||
|
tmp = get_entry(parent, k, krb5_config_string);
|
||||||
|
tmp->u.string = cfstring2cstring(value);
|
||||||
|
} else if (CFGetTypeID(value) == CFDictionaryGetTypeID()) {
|
||||||
|
tmp = get_entry(parent, k, krb5_config_list);
|
||||||
|
CFDictionaryApplyFunction(value, convert_content, &tmp->u.list);
|
||||||
|
} else {
|
||||||
|
/* log */
|
||||||
|
}
|
||||||
|
free(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
parse_plist_config(krb5_context context, const char *path, krb5_config_section **parent)
|
||||||
|
{
|
||||||
|
CFReadStreamRef s;
|
||||||
|
CFDictionaryRef d;
|
||||||
|
CFErrorRef e;
|
||||||
|
CFURLRef url;
|
||||||
|
CFDataRef p;
|
||||||
|
|
||||||
|
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE);
|
||||||
|
if (url == NULL) {
|
||||||
|
krb5_clear_error_message(context);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
|
||||||
|
CFRelease(url);
|
||||||
|
if (s == NULL) {
|
||||||
|
krb5_clear_error_message(context);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CFReadStreamOpen(s)) {
|
||||||
|
CFRelease(s);
|
||||||
|
krb5_clear_error_message(context);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = (CFDictionaryRef)CFPropertyListCreateWithStream (kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, &e);
|
||||||
|
CFRelease(s);
|
||||||
|
if (d == NULL) {
|
||||||
|
krb5_clear_error_message(context);
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFDictionaryApplyFunction(d, convert_content, parent);
|
||||||
|
CFRelease(d);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the config file `fname', generating the structures into `res'
|
* Parse the config file `fname', generating the structures into `res'
|
||||||
* returning error messages in `error_message'
|
* returning error messages in `error_message'
|
||||||
@@ -280,6 +379,18 @@ krb5_config_parse_debug (struct fileptr *f,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_plist_file(const char *fname)
|
||||||
|
{
|
||||||
|
size_t len = strlen(fname);
|
||||||
|
char suffix[] = ".plist";
|
||||||
|
if (len < sizeof(suffix))
|
||||||
|
return 0;
|
||||||
|
if (strcasecmp(&fname[len - (sizeof(suffix) - 1)], suffix) != 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a configuration file and add the result into res. This
|
* Parse a configuration file and add the result into res. This
|
||||||
* interface can be used to parse several configuration files into one
|
* interface can be used to parse several configuration files into one
|
||||||
@@ -309,9 +420,15 @@ krb5_config_parse_file_multi (krb5_context context,
|
|||||||
* current users home directory. The behavior can be disabled and
|
* current users home directory. The behavior can be disabled and
|
||||||
* enabled by calling krb5_set_home_dir_access().
|
* enabled by calling krb5_set_home_dir_access().
|
||||||
*/
|
*/
|
||||||
if (_krb5_homedir_access(context) && fname[0] == '~' && fname[1] == '/') {
|
if (fname[0] == '~' && fname[1] == '/') {
|
||||||
const char *home = NULL;
|
const char *home = NULL;
|
||||||
|
|
||||||
|
if (!_krb5_homedir_access(context)) {
|
||||||
|
krb5_set_error_message(context, EPERM,
|
||||||
|
"Access to home directory not allowed");
|
||||||
|
return EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
if(!issuid())
|
if(!issuid())
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
|
|
||||||
@@ -331,24 +448,42 @@ krb5_config_parse_file_multi (krb5_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.f = fopen(fname, "r");
|
if (is_plist_file(fname)) {
|
||||||
f.s = NULL;
|
#ifdef __APPLE__
|
||||||
if(f.f == NULL) {
|
ret = parse_plist_config(context, fname, res);
|
||||||
ret = errno;
|
if (ret) {
|
||||||
krb5_set_error_message (context, ret, "open %s: %s",
|
krb5_set_error_message(context, ret,
|
||||||
fname, strerror(ret));
|
"Failed to parse plist %s", fname);
|
||||||
if (newfname)
|
if (newfname)
|
||||||
free(newfname);
|
free(newfname);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
krb5_set_error_message(context, ENOENT,
|
||||||
|
"no support for plist configuration files");
|
||||||
|
return ENOENT;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
f.f = fopen(fname, "r");
|
||||||
|
f.s = NULL;
|
||||||
|
if(f.f == NULL) {
|
||||||
|
ret = errno;
|
||||||
|
krb5_set_error_message (context, ret, "open %s: %s",
|
||||||
|
fname, strerror(ret));
|
||||||
|
if (newfname)
|
||||||
|
free(newfname);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = krb5_config_parse_debug (&f, res, &lineno, &str);
|
ret = krb5_config_parse_debug (&f, res, &lineno, &str);
|
||||||
fclose(f.f);
|
fclose(f.f);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str);
|
krb5_set_error_message (context, ret, "%s:%u: %s",
|
||||||
if (newfname)
|
fname, lineno, str);
|
||||||
free(newfname);
|
if (newfname)
|
||||||
return ret;
|
free(newfname);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newfname)
|
if (newfname)
|
||||||
free(newfname);
|
free(newfname);
|
||||||
|
Reference in New Issue
Block a user