Skip to content

Instantly share code, notes, and snippets.

@riton
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riton/f56329252e885275aa5e to your computer and use it in GitHub Desktop.
Save riton/f56329252e885275aa5e to your computer and use it in GitHub Desktop.
Remctl acl_check_pts
/**
* First idea that uses
* pr_IsAMemberOf() to accomplish
* what we want
*/
static enum config_status
acl_check_pts(const char *user, const char *ptsid, const char *file,
int lineno)
{
afs_int32 code;
idlist ids;
namelist names;
int i;
int rc = -1;
namelist list;
int j;
const char *afs_error;
char *error = NULL;
size_t error_len = 1024;
int (*cmp_usrs)(const char *, const char*) = &afs_CompareUsers;
enum config_status result;
size_t lsize = REMCTL_KRB5_LOCALNAME_MAX_LEN;
char *lname = NULL;
krb5_context krb_ctx = NULL;
krb5_principal princ = NULL;
krb5_error_code krb5_code = -1;
error = (char *) xmalloc(sizeof(char) * error_len);
memset(error, 0x0, error_len);
code = afs_GetGlobals(NULL);
if (code) {
afs_error = afs_error_message(code);
warn("%s:%d: initialization of AFS libraries failed: %s", file, lineno,
afs_error);
result = CONFIG_ERROR;
goto leave;
}
/* Convert principal to local name */
lname = (char *) xmalloc(sizeof(char) * lsize);
memset(lname, 0x0, lsize);
krb5_code = krb5_init_context(&krb_ctx);
krb5_code = krb5_parse_name(krb_ctx, user, &princ);
krb5_code = krb5_aname_to_localname(krb_ctx, princ, lsize, lname);
afs_int32 isamember = 0;
code = pr_IsAMemberOf(lname, ptsid, &isamember);
if (code != 0) {
afs_error = afs_error_message(code);
warn("%s:%d: fail to verify that %s is a member of PTS group %s: %s", file, lineno,
lname, ptsid, afs_error);
result = CONFIG_ERROR;
goto leave;
}
if (isamember) {
result = CONFIG_SUCCESS;
}
else {
result = CONFIG_NOMATCH;
leave:
if (error) {
free(error);
error = NULL;
}
if (lname != NULL) {
free(lname);
lname = NULL;
}
if (princ != NULL) {
krb5_free_principal(krb_ctx, princ);
princ = NULL;
}
if (krb_ctx != NULL) {
krb5_free_context(krb_ctx);
krb_ctx = NULL;
}
if (ids.idlist_val)
free(ids.idlist_val);
if (names.namelist_val)
free(names.namelist_val);
afs_CleanUp();
return result;
}
/**
* Seconde idea, taken from OpenAFS
* ptserver/pts.c file
*/
static enum config_status
acl_check_pts(const char *user, const char *ptsid, const char *file,
int lineno)
{
afs_int32 code;
idlist ids;
namelist names;
int i;
int rc = -1;
namelist list;
int j;
const char *afs_error;
char *error = NULL;
size_t error_len = 1024;
int (*cmp_usrs)(const char *, const char*) = &afs_CompareUsers;
enum config_status result;
size_t lsize = REMCTL_KRB5_LOCALNAME_MAX_LEN;
char *lname = NULL;
krb5_context krb_ctx = NULL;
krb5_principal princ = NULL;
krb5_error_code krb5_code = -1;
error = (char *) xmalloc(sizeof(char) * error_len);
memset(error, 0x0, error_len);
code = afs_GetGlobals(NULL);
if (code) {
afs_error = afs_error_message(code);
warn("%s:%d: initialization of AFS libraries failed: %s", file, lineno,
afs_error);
result = CONFIG_ERROR;
goto leave;
}
/* Convert principal to local name */
lname = (char *) xmalloc(sizeof(char) * lsize);
memset(lname, 0x0, lsize);
krb5_code = krb5_init_context(&krb_ctx);
krb5_code = krb5_parse_name(krb_ctx, user, &princ);
krb5_code = krb5_aname_to_localname(krb_ctx, princ, lsize, lname);
if (afs_GetNameOrId(ptsid, &ids, &names, error_len, error) != 0) {
warn("%s:%d: resolving PTS entry %s failed: %s", file, lineno,
ptsid, error);
result = CONFIG_ERROR;
goto leave;
}
afs_int32 id = ids.idlist_val[0];
char *name = names.namelist_val[0];
if (id == ANONYMOUSID) {
/* bad entry */
warn("%s:%d: bad PTS entry %s", file, lineno, ptsid);
result = CONFIG_ERROR;
goto leave;
}
if (id > 0) { /* We're dealing with a user */
if (cmp_usrs(lname, name) == 0)
result = CONFIG_SUCCESS;
else
result = CONFIG_NOMATCH;
goto leave;
}
list.namelist_val = 0;
list.namelist_len = 0;
/* Expand sub groups members */
code = pr_IDListExpandedMembers(id, &list);
if (code) {
afs_error = afs_error_message(code);
warn("%s:%d: get membership of %s (id: %d) failed: %s", file, lineno,
ptsid, id, afs_error);
result = CONFIG_ERROR;
goto leave;
}
for (j = 0; j < list.namelist_len; j++) {
if (cmp_usrs(lname, list.namelist_val[j]) == 0) {
result = CONFIG_SUCCESS;
goto leave;
}
}
if (list.namelist_val)
free(list.namelist_val);
result = CONFIG_NOMATCH;
leave:
if (error) {
free(error);
error = NULL;
}
if (lname != NULL) {
free(lname);
lname = NULL;
}
if (princ != NULL) {
krb5_free_principal(krb_ctx, princ);
princ = NULL;
}
if (krb_ctx != NULL) {
krb5_free_context(krb_ctx);
krb_ctx = NULL;
}
if (ids.idlist_val)
free(ids.idlist_val);
if (names.namelist_val)
free(names.namelist_val);
afs_CleanUp();
return result;
}
/**
* AFS utils for remctl
* Heavily inspired (or taken) from OpenAFS source code
*/
int
afs_CleanUp(void)
{
if (pruclient) {
/* Need to shutdown the ubik_client & other connections */
pr_End();
rx_Finalize();
}
return 0;
}
int
afs_GetGlobals(const char *cell)
{
afs_int32 code;
afs_int32 sec = 0; // NoAuth
const char* confdir;
confdir = AFSDIR_CLIENT_ETC_DIRPATH;
afs_CleanUp();
code = pr_Initialize(sec, confdir, (char *)cell);
return code;
}
int
afs_GetNameOrId(const char *userid,
struct idlist *lids,
struct namelist *lnames,
const size_t error_len,
char *error)
{
afs_int32 code = 0;
int n = 1, nd = 0, nm = 0, id, x;
struct cmd_item *i;
struct namelist names, tnames; /* local copy, if not ret. names */
struct idlist ids, tids; /* local copy, if not ret. ids */
int goodCount = 0;
//char *error = NULL;
const char *afs_error;
/* Initialise our outputs */
memset(lids, 0, sizeof(struct idlist));
if (lnames)
memset(lnames, 0, sizeof(struct namelist));
lids->idlist_val = malloc(n * sizeof(afs_int32));
lids->idlist_len = n;
ids.idlist_val = malloc(n * sizeof(afs_int32));
ids.idlist_len = n;
names.namelist_val = malloc(n * PR_MAXNAMELEN);
names.namelist_len = n;
if (lnames) {
lnames->namelist_val = malloc(n * PR_MAXNAMELEN);
lnames->namelist_len = 0;
}
tnames.namelist_val = malloc(PR_MAXNAMELEN);
strncpy(tnames.namelist_val[0], userid, PR_MAXNAMELEN);
tnames.namelist_len = 1;
tids.idlist_len = 0;
tids.idlist_val = 0;
code = pr_NameToId(&tnames, &tids);
if (!code && (tids.idlist_val[0] != ANONYMOUSID)
|| (code = util_GetInt32((char *)userid, &id))) {
/* Assume it's a name instead */
strncpy(names.namelist_val[nm++], userid, PR_MAXNAMELEN);
} else {
ids.idlist_val[nd++] = id;
}
if (tnames.namelist_val != NULL) {
free(tnames.namelist_val);
tnames.namelist_val = NULL;
}
names.namelist_len = nm;
ids.idlist_len = nd;
tids.idlist_len = nd = nm = 0;
tids.idlist_val = 0;
code = pr_NameToId(&names, &tids);
if (code) {
afs_error = afs_error_message(code);
snprintf(error, error_len - 1, "%s so couldn't loop up name", afs_error);
error[error_len - 1] = '\0';
goto leave;
}
else {
for (n = 0; n < tids.idlist_len; n++) {
if (tids.idlist_val[n] == ANONYMOUSID) {
afs_error = afs_error_message(PRNOENT);
snprintf(error, error_len - 1, "%s so couln't loop up id for %s", afs_error,
names.namelist_val[n]);
error[error_len - 1] = '\0';
goto leave;
} else
goodCount++;
lids->idlist_val[nd] = tids.idlist_val[n];
if (lnames)
strcpy(lnames->namelist_val[nd], names.namelist_val[n]);
nd++;
}
}
for (x = 0; x < ids.idlist_len; x++) {
lids->idlist_val[nd + x] = ids.idlist_val[x];
}
lids->idlist_len = nd + x;
if (!code && lnames) {
tnames.namelist_val = 0;
tnames.namelist_len = 0;
code = pr_IdToName(&ids, &tnames);
if (code) {
afs_error = afs_error_message(code);
snprintf(error, error_len - 1, "%s translating ids", afs_error);
error[error_len - 1] = '\0';
goto leave;
}
else {
goodCount++;
if (lnames) {
for (x = 0; x < ids.idlist_len; x++)
strcpy(lnames->namelist_val[nd + x], tnames.namelist_val[x]);
lnames->namelist_len = nd + x;
}
}
}
leave:
/* treat things as working if any of the lookups worked */
if (goodCount == 0) {
code = PRNOENT;
afs_error = afs_error_message(code);
snprintf(error, error_len - 1, "%s so couln't loop up given id", afs_error);
error[error_len - 1] = '\0';
}
if (code) {
return -1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment