diff options
Diffstat (limited to 'source4/rpc_server/samr/samdb.c')
-rw-r--r-- | source4/rpc_server/samr/samdb.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/source4/rpc_server/samr/samdb.c b/source4/rpc_server/samr/samdb.c new file mode 100644 index 0000000000..ac58fe2c01 --- /dev/null +++ b/source4/rpc_server/samr/samdb.c @@ -0,0 +1,189 @@ +/* + Unix SMB/CIFS implementation. + + interface functions for the sam database + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +/* + the way that unix fcntl locking works forces us to have a static ldb + handle here rather than a much more sensible approach of having the + ldb handle as part of the samr_Connect() pipe state. Otherwise we + would try to open the ldb more than once, and tdb would rightly + refuse the second open due to the broken nature of unix locking. +*/ +static struct ldb_context *sam_db; + +/* + connect to the SAM database + return 0 on success, -1 on failure + */ +int samdb_connect(void) +{ + if (sam_db != NULL) { + return 0; + } + sam_db = ldb_connect(lp_sam_url(), 0, NULL); + + if (sam_db == NULL) { + return -1; + } + + return 0; +} + + +/* + search the sam for the specified attributes - va_list varient +*/ +int samdb_search_v(struct ldb_message ***res, + const char * const *attrs, + const char *format, + va_list ap) +{ + char *expr = NULL; + int count; + + vasprintf(&expr, format, ap); + if (expr == NULL) { + return -1; + } + + count = ldb_search(sam_db, NULL, LDB_SCOPE_SUBTREE, expr, attrs, res); + + free(expr); + + return count; +} + + +/* + search the sam for the specified attributes - varargs varient +*/ +int samdb_search(struct ldb_message ***res, + const char * const *attrs, + const char *format, ...) +{ + va_list ap; + int count; + + va_start(ap, format); + count = samdb_search_v(res, attrs, format, ap); + va_end(ap); + + return count; +} + + +/* + search the sam for a single string attribute in exactly 1 record +*/ +const char *samdb_search_string(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *format, ...) +{ + va_list ap; + int count; + const char * const attrs[2] = { attr_name, NULL }; + struct ldb_message **res = NULL; + const char *str = NULL; + + va_start(ap, format); + count = samdb_search_v(&res, attrs, format, ap); + va_end(ap); + + if (count == 0) { + return NULL; + } + + /* make sure its single valued */ + if (count != 1 || + res[0]->num_elements != 1 || + res[0]->elements[0].num_values != 1 || + res[0]->elements[0].values[0].data == NULL) { + DEBUG(1,("samdb: search for %s %s not single valued\n", + attr_name, format)); + ldb_search_free(sam_db, res); + return NULL; + } + + str = talloc_strndup(mem_ctx, + res[0]->elements[0].values[0].data, + res[0]->elements[0].values[0].length); + + ldb_search_free(sam_db, res); + + return str; +} + + +/* + search the sam for multipe records each giving a single string attribute + return the number of matches, or -1 on error +*/ +int samdb_search_string_multiple(TALLOC_CTX *mem_ctx, + char ***strs, + const char *attr_name, + const char *format, ...) +{ + va_list ap; + int count, i; + const char * const attrs[2] = { attr_name, NULL }; + struct ldb_message **res = NULL; + + va_start(ap, format); + count = samdb_search_v(&res, attrs, format, ap); + va_end(ap); + + if (count <= 0) { + return count; + } + + /* make sure its single valued */ + for (i=0;i<count;i++) { + if (res[i]->num_elements != 1 || + res[i]->elements[0].num_values != 1 || + res[i]->elements[0].values[0].data == NULL) { + DEBUG(1,("samdb: search for %s %s not single valued\n", + attr_name, format)); + ldb_search_free(sam_db, res); + return -1; + } + } + + *strs = talloc_array_p(mem_ctx, char *, count+1); + if (! *strs) { + ldb_search_free(sam_db, res); + return -1; + } + + for (i=0;i<count;i++) { + (*strs)[i] = talloc_strndup(mem_ctx, + res[i]->elements[0].values[0].data, + res[i]->elements[0].values[0].length); + } + (*strs)[count] = NULL; + + ldb_search_free(sam_db, res); + + return count; +} + |