Author: metze Date: 2005-08-11 12:59:14 +0000 (Thu, 11 Aug 2005) New Revision: 406
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=lorikeet&rev=406 Log: I got the basic infrastructure for setting the nttoken working it currently uses just strings, but I'll pass an ndr_encoded struct security_token as next step metze Modified: trunk/ntacl-lsm/main.c Changeset: Modified: trunk/ntacl-lsm/main.c =================================================================== --- trunk/ntacl-lsm/main.c 2005-08-11 12:55:49 UTC (rev 405) +++ trunk/ntacl-lsm/main.c 2005-08-11 12:59:14 UTC (rev 406) @@ -108,8 +108,193 @@ return result; } +#define NTACL_TASK_SECURITY_MAGIC (unsigned long)('N'<<24 | 'T'<<16 | 'T'<<8 | 'S') +struct ntacl_task_security_struct { + unsigned long magic; + struct task_struct *task; + char *current_sid_string; + char *prev_sid_string; + char *exec_sid_string; + char *fscreate_sid_string; +}; +static inline struct ntacl_task_security_struct *ntacl_task_security_check(void *p) +{ + struct ntacl_task_security_struct *tsec = p; + if (!tsec) { + return NULL; + } + if (tsec->magic != NTACL_TASK_SECURITY_MAGIC) { + return NULL; + } + return tsec; +} + +static int ntacl_task_alloc_security(struct task_struct *task) +{ + struct ntacl_task_security_struct *cur_tsec = ntacl_task_security_check(current->security); + struct ntacl_task_security_struct *task_tsec = NULL; + + if (!cur_tsec) goto done; + + task_tsec = talloc(NULL, struct ntacl_task_security_struct); + if (!task_tsec) return -ENOMEM; + task_tsec->magic = NTACL_TASK_SECURITY_MAGIC; + task_tsec->task = task; +#define _TMP_COPY_STRING(member) do {\ + if (!cur_tsec->member) {\ + task_tsec->member = NULL;\ + } else {\ + task_tsec->member = talloc_strdup(task_tsec, cur_tsec->member);\ + if (!task_tsec->member) {\ + talloc_free(task_tsec);\ + return -ENOMEM;\ + }\ + }\ +} while(0) + _TMP_COPY_STRING(current_sid_string); + _TMP_COPY_STRING(prev_sid_string); + _TMP_COPY_STRING(exec_sid_string); + _TMP_COPY_STRING(fscreate_sid_string); +#undef _TMP_COPY_STRING + +done: + task->security = task_tsec; + return 0; +} + +static void ntacl_task_free_security(struct task_struct *task) +{ + struct ntacl_task_security_struct *task_tsec = ntacl_task_security_check(task->security); + + if (!task_tsec) goto done; + + talloc_free(task_tsec); +done: + task->security = NULL; + return; +} + +static int ntacl_getprocattr(struct task_struct *task, char *name, void *value, size_t size) +{ + struct ntacl_task_security_struct *task_tsec = ntacl_task_security_check(task->security); + char *sid_string = NULL; + size_t len; + + printk("ntacl_getprocattr(%p, \"%s\", %p, %u)\n", + task, name, value, size); + dump_stack(); + + if (current != task) { + printk("ntacl_getprocattr: current(%p) task(%p): allowed for now\n", current, task); + /*return -EACCES;*/ + } + + if (strcmp("current", name) == 0) { + if (task_tsec) { + sid_string = task_tsec->current_sid_string; + } + } else if (strcmp("prev", name) == 0) { + if (task_tsec) { + sid_string = task_tsec->prev_sid_string; + } + } else if (strcmp("exec", name) == 0) { + if (task_tsec) { + sid_string = task_tsec->exec_sid_string; + } + } else if (strcmp("fscreate", name) == 0) { + if (task_tsec) { + sid_string = task_tsec->fscreate_sid_string; + } + } else { + return -EINVAL; + } + + if (!sid_string) return 0; + + len = strlen(sid_string)+1; + if (size < len) return -ERANGE; + + memcpy(value, sid_string, len); + return len; +} + +static inline int ntacl_is_string(const char *s, size_t l) +{ + size_t i; + if (s[l] != '\0') return -EINVAL; + + for (i = 0; i<l; i++) { + if (s[i] == '\0') return -EINVAL; + } + return 0; +} + +static int ntacl_setprocattr(struct task_struct *task, char *name, void *value, size_t size) +{ + struct ntacl_task_security_struct *task_tsec = ntacl_task_security_check(task->security); + char *sid_string = NULL; + int ret; + + printk("ntacl_setprocattr(%p, \"%s\", %p, %u)\n", + task, name, value, size); + dump_stack(); + + if (current != task) { + printk("ntacl_setprocattr: current(%p) task(%p): allowed for now\n", current, task); + /*return -EACCES;*/ + } + + /* TODO: check if the task allowed to change its attr's */ + + ret = ntacl_is_string(value, size); + if (ret) { + printk("ntacl_setprocattr: %d,%d %s : %d\n", size, strlen(value), (char *)value, ret); + return ret; + } + + if (!task_tsec) { + task_tsec = talloc(NULL, struct ntacl_task_security_struct); + if (!task_tsec) return -ENOMEM; + task_tsec->magic = NTACL_TASK_SECURITY_MAGIC; + task_tsec->task = task; + task_tsec->current_sid_string = NULL; + task_tsec->prev_sid_string = NULL; + task_tsec->exec_sid_string = NULL; + task_tsec->fscreate_sid_string = NULL; + task->security = task_tsec; + } + + sid_string = talloc_strndup(task_tsec, value, size); + if (!sid_string) return -EINVAL; + +#define _TMP_REPLACE_STRING(cur, new) do {\ + if (cur) talloc_free(cur);\ + cur = new;\ +} while (0) + if (strcmp("current", name) == 0) { + _TMP_REPLACE_STRING(task_tsec->current_sid_string, sid_string); + } else if (strcmp("prev", name) == 0) { + _TMP_REPLACE_STRING(task_tsec->prev_sid_string, sid_string); + } else if (strcmp("exec", name) == 0) { + _TMP_REPLACE_STRING(task_tsec->exec_sid_string, sid_string); + } else if (strcmp("fscreate", name) == 0) { + _TMP_REPLACE_STRING(task_tsec->fscreate_sid_string, sid_string); + } else { + return -EINVAL; + } +#undef _TMP_REPLACE_STRING + + return size; +} + static struct security_operations ntacl_security_ops = { - .inode_unlink = ntacl_unlink, + .inode_unlink = ntacl_unlink, + + .task_alloc_security = ntacl_task_alloc_security, + .task_free_security = ntacl_task_free_security, + + .getprocattr = ntacl_getprocattr, + .setprocattr = ntacl_setprocattr }; static int secondary; /* Remember how we were registered */ @@ -130,7 +315,7 @@ secondary = 1; } - printk(KERN_INFO "NTACL module initialised\n"); + printk("NTACL module initialised\n"); return 0; }
