summaryrefslogtreecommitdiffstats
path: root/source3/lib/netapi/examples
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/netapi/examples')
-rw-r--r--source3/lib/netapi/examples/common.c249
-rw-r--r--source3/lib/netapi/examples/common.h18
-rw-r--r--source3/lib/netapi/examples/dsgetdc/dsgetdc.c101
-rw-r--r--source3/lib/netapi/examples/file/file_close.c83
-rw-r--r--source3/lib/netapi/examples/file/file_enum.c146
-rw-r--r--source3/lib/netapi/examples/file/file_getinfo.c112
-rw-r--r--source3/lib/netapi/examples/getdc/getdc.c86
-rw-r--r--source3/lib/netapi/examples/group/group_add.c90
-rw-r--r--source3/lib/netapi/examples/group/group_adduser.c91
-rw-r--r--source3/lib/netapi/examples/group/group_del.c82
-rw-r--r--source3/lib/netapi/examples/group/group_deluser.c91
-rw-r--r--source3/lib/netapi/examples/group/group_enum.c153
-rw-r--r--source3/lib/netapi/examples/group/group_getinfo.c127
-rw-r--r--source3/lib/netapi/examples/group/group_getusers.c132
-rw-r--r--source3/lib/netapi/examples/group/group_setinfo.c142
-rw-r--r--source3/lib/netapi/examples/group/group_setusers.c142
-rw-r--r--source3/lib/netapi/examples/join/djoin.c166
-rw-r--r--source3/lib/netapi/examples/join/getjoinableous.c110
-rw-r--r--source3/lib/netapi/examples/join/getjoininformation.c105
-rw-r--r--source3/lib/netapi/examples/join/netdomjoin.c104
-rw-r--r--source3/lib/netapi/examples/join/provision_computer_account.c122
-rw-r--r--source3/lib/netapi/examples/join/rename_machine.c101
-rw-r--r--source3/lib/netapi/examples/join/request_offline_domain_join.c97
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_add.c106
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_addmembers.c141
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_del.c83
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_delmembers.c141
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_enum.c126
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_getinfo.c112
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_getmembers.c165
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_setinfo.c128
-rw-r--r--source3/lib/netapi/examples/localgroup/localgroup_setmembers.c146
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/logo-small.pngbin0 -> 4485 bytes
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/logo.pngbin0 -> 9329 bytes
-rw-r--r--source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c1888
-rwxr-xr-xsource3/lib/netapi/examples/netdomjoin-gui/samba.icobin0 -> 1406 bytes
-rw-r--r--source3/lib/netapi/examples/netlogon/netlogon_control.c143
-rw-r--r--source3/lib/netapi/examples/netlogon/netlogon_control2.c147
-rw-r--r--source3/lib/netapi/examples/netlogon/nltest.c677
-rw-r--r--source3/lib/netapi/examples/server/remote_tod.c83
-rw-r--r--source3/lib/netapi/examples/server/server_getinfo.c136
-rw-r--r--source3/lib/netapi/examples/share/share_add.c105
-rw-r--r--source3/lib/netapi/examples/share/share_del.c85
-rw-r--r--source3/lib/netapi/examples/share/share_enum.c142
-rw-r--r--source3/lib/netapi/examples/share/share_getinfo.c152
-rw-r--r--source3/lib/netapi/examples/share/share_setinfo.c105
-rw-r--r--source3/lib/netapi/examples/shutdown/shutdown_abort.c76
-rw-r--r--source3/lib/netapi/examples/shutdown/shutdown_init.c94
-rw-r--r--source3/lib/netapi/examples/user/user_add.c103
-rw-r--r--source3/lib/netapi/examples/user/user_chgpwd.c99
-rw-r--r--source3/lib/netapi/examples/user/user_del.c82
-rw-r--r--source3/lib/netapi/examples/user/user_dispinfo.c100
-rw-r--r--source3/lib/netapi/examples/user/user_enum.c157
-rw-r--r--source3/lib/netapi/examples/user/user_getgroups.c133
-rw-r--r--source3/lib/netapi/examples/user/user_getinfo.c293
-rw-r--r--source3/lib/netapi/examples/user/user_getlocalgroups.c122
-rw-r--r--source3/lib/netapi/examples/user/user_modalsget.c131
-rw-r--r--source3/lib/netapi/examples/user/user_modalsset.c132
-rw-r--r--source3/lib/netapi/examples/user/user_setgroups.c144
-rw-r--r--source3/lib/netapi/examples/user/user_setinfo.c200
-rw-r--r--source3/lib/netapi/examples/wscript_build72
61 files changed, 9399 insertions, 0 deletions
diff --git a/source3/lib/netapi/examples/common.c b/source3/lib/netapi/examples/common.c
new file mode 100644
index 0000000..72d7150
--- /dev/null
+++ b/source3/lib/netapi/examples/common.c
@@ -0,0 +1,249 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <popt.h>
+#include <netapi.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <iconv.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#include "common.h"
+
+void popt_common_callback(poptContext con,
+ enum poptCallbackReason reason,
+ const struct poptOption *opt,
+ const char *arg, const void *data)
+{
+ struct libnetapi_ctx *ctx = NULL;
+
+ libnetapi_getctx(&ctx);
+
+ if (reason == POPT_CALLBACK_REASON_PRE) {
+ }
+
+ if (reason == POPT_CALLBACK_REASON_POST) {
+ }
+
+ if (!opt) {
+ return;
+ }
+ switch (opt->val) {
+ case 'U': {
+ char *puser = strdup(arg);
+ char *p = NULL;
+
+ if ((p = strchr(puser,'%'))) {
+ size_t len;
+ *p = 0;
+ libnetapi_set_username(ctx, puser);
+ libnetapi_set_password(ctx, p+1);
+ len = strlen(p+1);
+ memset(strchr(arg,'%')+1,'X',len);
+ } else {
+ libnetapi_set_username(ctx, puser);
+ }
+ free(puser);
+ break;
+ }
+ case 'd':
+ libnetapi_set_debuglevel(ctx, arg);
+ break;
+ case 'p':
+ libnetapi_set_password(ctx, arg);
+ break;
+ case 'k':
+ libnetapi_set_use_kerberos(ctx);
+ break;
+ }
+}
+
+struct poptOption popt_common_netapi_examples[] = {
+ {
+ .argInfo = POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST,
+ .arg = (void *)popt_common_callback,
+ },
+ {
+ .longName = "user",
+ .shortName = 'U',
+ .argInfo = POPT_ARG_STRING,
+ .val = 'U',
+ .descrip = "Username used for connection",
+ .argDescrip = "USERNAME",
+ },
+ {
+ .longName = "password",
+ .shortName = 'p',
+ .argInfo = POPT_ARG_STRING,
+ .val = 'p',
+ .descrip = "Password used for connection",
+ .argDescrip = "PASSWORD",
+ },
+ {
+ .longName = "debuglevel",
+ .shortName = 'd',
+ .argInfo = POPT_ARG_STRING,
+ .val = 'd',
+ .descrip = "Debuglevel",
+ .argDescrip = "DEBUGLEVEL",
+ },
+ {
+ .longName = "kerberos",
+ .shortName = 'k',
+ .argInfo = POPT_ARG_NONE,
+ .val = 'k',
+ .descrip = "Use Kerberos",
+ },
+ POPT_TABLEEND
+};
+
+char *netapi_read_file(const char *filename, uint32_t *psize)
+{
+ int fd;
+ FILE *file = NULL;
+ char *p = NULL;
+ size_t size = 0;
+ size_t chunk = 1024;
+ size_t maxsize = SIZE_MAX;
+ int err;
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ goto fail;
+ }
+
+ file = fdopen(fd, "r");
+ if (file == NULL) {
+ goto fail;
+ }
+
+ while (size < maxsize) {
+ char *tmp = NULL;
+ size_t newbufsize;
+ size_t nread;
+
+ chunk = MIN(chunk, (maxsize - size));
+
+ newbufsize = size + (chunk+1); /* chunk+1 can't overflow */
+ if (newbufsize < size) {
+ goto fail; /* overflow */
+ }
+
+ tmp = realloc(p, sizeof(char) * newbufsize);
+ if (tmp == NULL) {
+ free(p);
+ p = NULL;
+ goto fail;
+ }
+ p = tmp;
+
+ nread = fread(p+size, 1, chunk, file);
+ size += nread;
+
+ if (nread != chunk) {
+ break;
+ }
+ }
+
+ err = ferror(file);
+ if (err != 0) {
+ free(p);
+ goto fail;
+ }
+
+ p[size] = '\0';
+
+ if (psize != NULL) {
+ *psize = size;
+ }
+ fail:
+ if (file != NULL) {
+ fclose(file);
+ }
+ if (fd >= 0) {
+ close(fd);
+ }
+
+ return p;
+}
+
+int netapi_save_file(const char *fname, void *ppacket, size_t length)
+{
+ int fd;
+ fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (fd == -1) {
+ perror(fname);
+ return -1;
+ }
+ if (write(fd, ppacket, length) != length) {
+ fprintf(stderr,"Failed to write %s\n", fname);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ return 0;
+}
+
+int netapi_save_file_ucs2(const char *fname, const char *str)
+{
+ char *str_p = NULL;
+ char *ucs2_str = NULL;
+ size_t str_len = 0;
+ size_t ucs2_str_len = 0;
+ iconv_t cd;
+ int ret;
+ char *start;
+ size_t start_len;
+ char *p;
+
+ str_len = strlen(str) + 1;
+ ucs2_str_len = 2 * str_len; /* room for ucs2 */
+ ucs2_str_len += 2;
+
+ ucs2_str = calloc(ucs2_str_len, sizeof(char));
+ if (ucs2_str == NULL) {
+ return -1;
+ }
+ p = ucs2_str; /* store for free */
+
+ ucs2_str[0] = 0xff;
+ ucs2_str[1] = 0xfe;
+
+ start = ucs2_str;
+ start_len = ucs2_str_len;
+
+ ucs2_str += 2;
+ ucs2_str_len -= 2;
+
+ cd = iconv_open("UTF-16LE", "ASCII");
+ if (cd == (iconv_t)-1) {
+ free(p);
+ return -1;
+ }
+
+ str_p = (void *)((uintptr_t)str);
+
+ ret = iconv(cd,
+ &str_p,
+ &str_len,
+ &ucs2_str,
+ &ucs2_str_len);
+ if (ret == -1) {
+ free(p);
+ return -1;
+ }
+ iconv_close(cd);
+
+ ret = netapi_save_file(fname, start, start_len);
+ free(p);
+
+ return ret;
+}
diff --git a/source3/lib/netapi/examples/common.h b/source3/lib/netapi/examples/common.h
new file mode 100644
index 0000000..df7f176
--- /dev/null
+++ b/source3/lib/netapi/examples/common.h
@@ -0,0 +1,18 @@
+#include <popt.h>
+
+void popt_common_callback(poptContext con,
+ enum poptCallbackReason reason,
+ const struct poptOption *opt,
+ const char *arg, const void *data);
+
+extern struct poptOption popt_common_netapi_examples[];
+
+#ifndef POPT_TABLEEND
+#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
+#endif
+
+#define POPT_COMMON_LIBNETAPI_EXAMPLES { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_netapi_examples, 0, "Common samba netapi example options:", NULL },
+
+char *netapi_read_file(const char *filename, uint32_t *psize);
+int netapi_save_file(const char *fname, void *ppacket, size_t length);
+int netapi_save_file_ucs2(const char *fname, const char *str);
diff --git a/source3/lib/netapi/examples/dsgetdc/dsgetdc.c b/source3/lib/netapi/examples/dsgetdc/dsgetdc.c
new file mode 100644
index 0000000..6265e66
--- /dev/null
+++ b/source3/lib/netapi/examples/dsgetdc/dsgetdc.c
@@ -0,0 +1,101 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * DsGetDcName query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+
+ const char *hostname = NULL;
+ const char *domain = NULL;
+ uint32_t flags = 0;
+ struct DOMAIN_CONTROLLER_INFO *info = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ { "flags", 0, POPT_ARG_INT, NULL, 'f', "Query flags", "FLAGS" },
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("dsgetdc", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname domainname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ case 'f':
+ sscanf(poptGetOptArg(pc), "%x", &flags);
+ }
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ domain = poptGetArg(pc);
+
+ /* DsGetDcName */
+
+ status = DsGetDcName(hostname, domain, NULL, NULL, flags, &info);
+ if (status != 0) {
+ printf("DsGetDcName failed with: %s\n",
+ libnetapi_errstr(status));
+ return status;
+ }
+
+ printf("DC Name:\t\t%s\n", info->domain_controller_name);
+ printf("DC Address:\t\t%s\n", info->domain_controller_address);
+ printf("DC Address Type:\t%d\n", info->domain_controller_address_type);
+ printf("Domain Name:\t\t%s\n", info->domain_name);
+ printf("DNS Forest Name:\t%s\n", info->dns_forest_name);
+ printf("DC flags:\t\t0x%08x\n", info->flags);
+ printf("DC Sitename:\t\t%s\n", info->dc_site_name);
+ printf("Client Sitename:\t%s\n", info->client_site_name);
+
+ out:
+ NetApiBufferFree(info);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/file/file_close.c b/source3/lib/netapi/examples/file/file_close.c
new file mode 100644
index 0000000..759173a
--- /dev/null
+++ b/source3/lib/netapi/examples/file/file_close.c
@@ -0,0 +1,83 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetFileClose query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t fileid = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("file_close", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname fileid");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ fileid = atoi(poptGetArg(pc));
+
+ /* NetFileClose */
+
+ status = NetFileClose(hostname, fileid);
+ if (status != 0) {
+ printf("NetFileClose failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/file/file_enum.c b/source3/lib/netapi/examples/file/file_enum.c
new file mode 100644
index 0000000..5fbb285
--- /dev/null
+++ b/source3/lib/netapi/examples/file/file_enum.c
@@ -0,0 +1,146 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetFileEnum query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *basepath = NULL;
+ const char *username = NULL;
+ uint32_t level = 3;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int i;
+
+ struct FILE_INFO_2 *i2 = NULL;
+ struct FILE_INFO_3 *i3 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("file_enum", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname basepath username level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ basepath = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetFileEnum */
+
+ do {
+
+ status = NetFileEnum(hostname,
+ basepath,
+ username,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 2:
+ i2 = (struct FILE_INFO_2 *)buffer;
+ break;
+ case 3:
+ i3 = (struct FILE_INFO_3 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 2:
+ printf("file_id: %d\n", i2->fi2_id);
+ i2++;
+ break;
+ case 3:
+ printf("file_id: %d\n", i3->fi3_id);
+ printf("permissions: %d\n", i3->fi3_permissions);
+ printf("num_locks: %d\n", i3->fi3_num_locks);
+ printf("pathname: %s\n", i3->fi3_pathname);
+ printf("username: %s\n", i3->fi3_username);
+ i3++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetFileEnum failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/file/file_getinfo.c b/source3/lib/netapi/examples/file/file_getinfo.c
new file mode 100644
index 0000000..9ad8305
--- /dev/null
+++ b/source3/lib/netapi/examples/file/file_getinfo.c
@@ -0,0 +1,112 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetFileGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t fileid = 0;
+ uint32_t level = 3;
+ uint8_t *buffer = NULL;
+
+ struct FILE_INFO_2 *i2 = NULL;
+ struct FILE_INFO_3 *i3 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("file_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname fileid");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ fileid = atoi(poptGetArg(pc));
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetFileGetInfo */
+
+ status = NetFileGetInfo(hostname,
+ fileid,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetFileGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 2:
+ i2 = (struct FILE_INFO_2 *)buffer;
+ printf("file_id: %d\n", i2->fi2_id);
+ break;
+ case 3:
+ i3 = (struct FILE_INFO_3 *)buffer;
+ printf("file_id: %d\n", i3->fi3_id);
+ printf("permissions: %d\n", i3->fi3_permissions);
+ printf("num_locks: %d\n", i3->fi3_num_locks);
+ printf("pathname: %s\n", i3->fi3_pathname);
+ printf("username: %s\n", i3->fi3_username);
+ break;
+ default:
+ break;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/getdc/getdc.c b/source3/lib/netapi/examples/getdc/getdc.c
new file mode 100644
index 0000000..98bb6a1
--- /dev/null
+++ b/source3/lib/netapi/examples/getdc/getdc.c
@@ -0,0 +1,86 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * GetDCName query
+ * Copyright (C) Guenther Deschner 2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+
+ const char *hostname = NULL;
+ const char *domain = NULL;
+ uint8_t *buffer = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("getdc", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname domainname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ domain = poptGetArg(pc);
+
+ /* NetGetDCName */
+
+ status = NetGetDCName(hostname, domain, &buffer);
+ if (status != 0) {
+ printf("GetDcName failed with: %s\n", libnetapi_errstr(status));
+ } else {
+ printf("%s\n", (char *)buffer);
+ }
+
+ out:
+ NetApiBufferFree(buffer);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_add.c b/source3/lib/netapi/examples/group/group_add.c
new file mode 100644
index 0000000..4da97c5
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_add.c
@@ -0,0 +1,90 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupAdd query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ struct GROUP_INFO_1 g1;
+ uint32_t parm_error = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_add", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ /* NetGroupAdd */
+
+ g1.grpi1_name = groupname;
+ g1.grpi1_comment = "Domain Group created using NetApi example code";
+
+ status = NetGroupAdd(hostname,
+ 1,
+ (uint8_t *)&g1,
+ &parm_error);
+ if (status != 0) {
+ printf("NetGroupAdd failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_adduser.c b/source3/lib/netapi/examples/group/group_adduser.c
new file mode 100644
index 0000000..253b3c5
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_adduser.c
@@ -0,0 +1,91 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupAddUser query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ const char *username = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_adduser", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname username");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ /* NetGroupAddUser */
+
+ status = NetGroupAddUser(hostname,
+ groupname,
+ username);
+ if (status != 0) {
+ printf("NetGroupAddUser failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_del.c b/source3/lib/netapi/examples/group/group_del.c
new file mode 100644
index 0000000..789e429
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_del.c
@@ -0,0 +1,82 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupDel query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_del", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ /* NetGroupDel */
+
+ status = NetGroupDel(hostname, groupname);
+ if (status != 0) {
+ printf("NetGroupDel failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_deluser.c b/source3/lib/netapi/examples/group/group_deluser.c
new file mode 100644
index 0000000..751ab5c
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_deluser.c
@@ -0,0 +1,91 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupDelUser query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ const char *username = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_deluser", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname username");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ /* NetGroupDelUser */
+
+ status = NetGroupDelUser(hostname,
+ groupname,
+ username);
+ if (status != 0) {
+ printf("NetGroupDelUser failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_enum.c b/source3/lib/netapi/examples/group/group_enum.c
new file mode 100644
index 0000000..fe2aee1
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_enum.c
@@ -0,0 +1,153 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupEnum query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int i;
+ char *sid_str = NULL;
+
+ struct GROUP_INFO_0 *info0 = NULL;
+ struct GROUP_INFO_1 *info1 = NULL;
+ struct GROUP_INFO_2 *info2 = NULL;
+ struct GROUP_INFO_3 *info3 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_enum", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetGroupEnum */
+
+ do {
+ status = NetGroupEnum(hostname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_INFO_1 *)buffer;
+ break;
+ case 2:
+ info2 = (struct GROUP_INFO_2 *)buffer;
+ break;
+ case 3:
+ info3 = (struct GROUP_INFO_3 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d group: %s\n", i, info0->grpi0_name);
+ info0++;
+ break;
+ case 1:
+ printf("#%d group: %s\n", i, info1->grpi1_name);
+ printf("#%d comment: %s\n", i, info1->grpi1_comment);
+ info1++;
+ break;
+ case 2:
+ printf("#%d group: %s\n", i, info2->grpi2_name);
+ printf("#%d comment: %s\n", i, info2->grpi2_comment);
+ printf("#%d rid: %d\n", i, info2->grpi2_group_id);
+ printf("#%d attributes: 0x%08x\n", i, info2->grpi2_attributes);
+ info2++;
+ break;
+ case 3:
+ printf("#%d group: %s\n", i, info3->grpi3_name);
+ printf("#%d comment: %s\n", i, info3->grpi3_comment);
+ if (ConvertSidToStringSid(info3->grpi3_group_sid,
+ &sid_str)) {
+ printf("#%d group_sid: %s\n", i, sid_str);
+ free(sid_str);
+ }
+ printf("#%d attributes: 0x%08x\n", i, info3->grpi3_attributes);
+ info3++;
+ break;
+
+
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetGroupEnum failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_getinfo.c b/source3/lib/netapi/examples/group/group_getinfo.c
new file mode 100644
index 0000000..2e5b793
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_getinfo.c
@@ -0,0 +1,127 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ struct GROUP_INFO_0 *g0;
+ struct GROUP_INFO_1 *g1;
+ struct GROUP_INFO_2 *g2;
+ struct GROUP_INFO_3 *g3;
+ char *sid_str = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetGroupGetInfo */
+
+ status = NetGroupGetInfo(hostname,
+ groupname,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetGroupGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 0:
+ g0 = (struct GROUP_INFO_0 *)buffer;
+ printf("name: %s\n", g0->grpi0_name);
+ break;
+ case 1:
+ g1 = (struct GROUP_INFO_1 *)buffer;
+ printf("name: %s\n", g1->grpi1_name);
+ printf("comment: %s\n", g1->grpi1_comment);
+ break;
+ case 2:
+ g2 = (struct GROUP_INFO_2 *)buffer;
+ printf("name: %s\n", g2->grpi2_name);
+ printf("comment: %s\n", g2->grpi2_comment);
+ printf("group_id: %d\n", g2->grpi2_group_id);
+ printf("attributes: %d\n", g2->grpi2_attributes);
+ break;
+ case 3:
+ g3 = (struct GROUP_INFO_3 *)buffer;
+ printf("name: %s\n", g3->grpi3_name);
+ printf("comment: %s\n", g3->grpi3_comment);
+ if (ConvertSidToStringSid(g3->grpi3_group_sid,
+ &sid_str)) {
+ printf("group_sid: %s\n", sid_str);
+ free(sid_str);
+ }
+ printf("attributes: %d\n", g3->grpi3_attributes);
+ break;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_getusers.c b/source3/lib/netapi/examples/group/group_getusers.c
new file mode 100644
index 0000000..72e79ec
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_getusers.c
@@ -0,0 +1,132 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupGetUsers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int i;
+
+ struct GROUP_USERS_INFO_0 *info0 = NULL;
+ struct GROUP_USERS_INFO_1 *info1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_getusers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetGroupGetUsers */
+
+ do {
+ status = NetGroupGetUsers(hostname,
+ groupname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_USERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_USERS_INFO_1 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d member: %s\n", i, info0->grui0_name);
+ info0++;
+ break;
+ case 1:
+ printf("#%d member: %s\n", i, info1->grui1_name);
+ printf("#%d attributes: %d\n", i, info1->grui1_attributes);
+ info1++;
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetGroupGetUsers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_setinfo.c b/source3/lib/netapi/examples/group/group_setinfo.c
new file mode 100644
index 0000000..cd30d8b
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_setinfo.c
@@ -0,0 +1,142 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupSetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ const char *option = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ uint32_t parm_err = 0;
+ struct GROUP_INFO_0 g0;
+ struct GROUP_INFO_1 g1;
+ struct GROUP_INFO_2 g2;
+ struct GROUP_INFO_3 g3;
+ struct GROUP_INFO_1002 g1002;
+ struct GROUP_INFO_1005 g1005;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_setinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level option");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ level = atoi(poptGetArg(pc));
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ option = poptGetArg(pc);
+
+ /* NetGroupSetInfo */
+
+ switch (level) {
+ case 0:
+ g0.grpi0_name = option;
+ buffer = (uint8_t *)&g0;
+ break;
+ case 1:
+ g1.grpi1_name = option; /* this one will be ignored */
+ g1.grpi1_comment = option;
+ buffer = (uint8_t *)&g1;
+ break;
+ case 2:
+ g2.grpi2_name = option; /* this one will be ignored */
+ g2.grpi2_comment = option;
+ g2.grpi2_group_id = 4711; /* this one will be ignored */
+ g2.grpi2_attributes = 7;
+ buffer = (uint8_t *)&g2;
+ break;
+ case 3:
+ g3.grpi3_name = option; /* this one will be ignored */
+ g3.grpi3_comment = option;
+ g2.grpi2_attributes = 7;
+ buffer = (uint8_t *)&g3;
+ break;
+ case 1002:
+ g1002.grpi1002_comment = option;
+ buffer = (uint8_t *)&g1002;
+ break;
+ case 1005:
+ g1005.grpi1005_attributes = atoi(option);
+ buffer = (uint8_t *)&g1005;
+ break;
+ }
+
+ status = NetGroupSetInfo(hostname,
+ groupname,
+ level,
+ buffer,
+ &parm_err);
+ if (status != 0) {
+ printf("NetGroupSetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/group/group_setusers.c b/source3/lib/netapi/examples/group/group_setusers.c
new file mode 100644
index 0000000..70cf105
--- /dev/null
+++ b/source3/lib/netapi/examples/group/group_setusers.c
@@ -0,0 +1,142 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetGroupSetUsers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t num_entries = 0;
+ const char **names = NULL;
+ int i = 0;
+ size_t buf_size = 0;
+
+ struct GROUP_USERS_INFO_0 *g0 = NULL;
+ struct GROUP_USERS_INFO_1 *g1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("group_setusers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ names = poptGetArgs(pc);
+ for (i=0; names[i] != NULL; i++) {
+ num_entries++;
+ }
+
+ switch (level) {
+ case 0:
+ buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g0);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g0[i].grui0_name = names[i];
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 1:
+ buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g1);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g1[i].grui1_name = names[i];
+ }
+
+ buffer = (uint8_t *)g1;
+ break;
+ default:
+ break;
+ }
+
+ /* NetGroupSetUsers */
+
+ status = NetGroupSetUsers(hostname,
+ groupname,
+ level,
+ buffer,
+ num_entries);
+ if (status != 0) {
+ printf("NetGroupSetUsers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/djoin.c b/source3/lib/netapi/examples/join/djoin.c
new file mode 100644
index 0000000..737f330
--- /dev/null
+++ b/source3/lib/netapi/examples/join/djoin.c
@@ -0,0 +1,166 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Offline Domain Join utility
+ * Copyright (C) Guenther Deschner 2021
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *domain = NULL;
+ const char *machine_name = NULL;
+ const char *windows_path = NULL;
+ const char *dcname = NULL;
+ const char *loadfile = NULL;
+ const char *savefile = NULL;
+ const char *machine_account_ou = NULL;
+ uint32_t options = 0;
+ uint8_t *provision_bin_data = NULL;
+ uint32_t provision_bin_data_size = 0;
+ const char *provision_text_data = NULL;
+ int provision = 0;
+ int requestodj = 0;
+ int default_password = 0;
+ int print_blob = 0;
+ int localos = 0;
+ int reuse = 0;
+
+ struct libnetapi_ctx *ctx = NULL;
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "provision", 0, POPT_ARG_NONE, &provision, 'D', "Create computer account in AD", NULL },
+ { "dcname", 0, POPT_ARG_STRING, &dcname, 'D', "Domain Controller Name", "DCNAME" },
+ { "machine_account_ou", 0, POPT_ARG_STRING, &machine_account_ou, 'D', "LDAP DN for Machine Account OU", "MACHINE_ACCOUNT_OU" },
+ { "domain", 0, POPT_ARG_STRING, &domain, 'D', "Domain name", "DOMAIN" },
+ { "machine_name", 0, POPT_ARG_STRING, &machine_name, 'D', "Computer Account Name", "MACHINENAME" },
+ { "defpwd", 0, POPT_ARG_NONE, &default_password, 'D', "Use default password for machine account (not recommended)", "" },
+ { "printblob", 0, POPT_ARG_NONE, &print_blob, 'D', "Print base64 encoded ODJ blob (for Windows answer files)", "" },
+ { "savefile", 0, POPT_ARG_STRING, &savefile, 'D', "Save ODJ blob to file (for Windows answer files)", "FILENAME" },
+ { "reuse", 0, POPT_ARG_NONE, &reuse, 'D', "Reuse machine account", "" },
+ { "requestodj", 0, POPT_ARG_NONE, &requestodj, 'D', "Load offline join data", NULL },
+ { "loadfile", 0, POPT_ARG_STRING, &loadfile, 'D', "Load file from previous provision", "FILENAME" },
+ { "localos", 0, POPT_ARG_NONE, &localos, 'D', "Request local OS to load offline join information", "" },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("djoin", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "[provision|requestodj]");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (provision) {
+
+ if (domain == NULL) {
+ printf("domain must be defined\n");
+ goto out;
+ }
+
+ if (machine_name == NULL) {
+ printf("machine_name must be defined\n");
+ goto out;
+ }
+
+ if (default_password) {
+ options |= NETSETUP_PROVISION_USE_DEFAULT_PASSWORD;
+ }
+
+ if (reuse) {
+ options |= NETSETUP_PROVISION_REUSE_ACCOUNT;
+ }
+
+ status = NetProvisionComputerAccount(domain,
+ machine_name,
+ machine_account_ou,
+ dcname,
+ options,
+ NULL,
+ 0,
+ &provision_text_data);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ if (print_blob) {
+ printf("Provision Text Data: %s\n", provision_text_data);
+ }
+
+ if (savefile != NULL) {
+ status = netapi_save_file_ucs2(savefile, provision_text_data);
+ if (status != 0) {
+ goto out;
+ }
+ }
+ }
+
+ if (requestodj) {
+
+ if (loadfile == NULL) {
+ printf("--loadfile <FILENAME> is required\n");
+ goto out;
+ }
+ provision_bin_data = (uint8_t *)netapi_read_file(loadfile,
+ &provision_bin_data_size);
+ if (provision_bin_data == NULL) {
+ printf("failed to read loadfile: %s\n", loadfile);
+ goto out;
+ }
+
+ if (localos) {
+ options |= NETSETUP_PROVISION_ONLINE_CALLER;
+ }
+
+ status = NetRequestOfflineDomainJoin(provision_bin_data,
+ provision_bin_data_size,
+ options,
+ windows_path);
+ free(provision_bin_data);
+
+ if (status != 0 && status != 0x00000a99) {
+ /* NERR_JoinPerformedMustRestart */
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/getjoinableous.c b/source3/lib/netapi/examples/join/getjoinableous.c
new file mode 100644
index 0000000..c0fba57
--- /dev/null
+++ b/source3/lib/netapi/examples/join/getjoinableous.c
@@ -0,0 +1,110 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Join Support (cmdline + netapi)
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *host_name = NULL;
+ const char *domain_name = NULL;
+ const char **ous = NULL;
+ uint32_t num_ous = 0;
+ struct libnetapi_ctx *ctx = NULL;
+ int i;
+ const char *username = NULL;
+ const char *password = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "domain", 0, POPT_ARG_STRING, NULL, 'D', "Domain name", "DOMAIN" },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("getjoinableous", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname domainname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ case 'D':
+ domain_name = poptGetOptArg(pc);
+ break;
+ }
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ host_name = poptGetArg(pc);
+
+ /* NetGetJoinableOUs */
+
+ status = libnetapi_get_username(ctx, &username);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+ status = libnetapi_get_password(ctx, &password);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ status = NetGetJoinableOUs(host_name,
+ domain_name,
+ username,
+ password,
+ &num_ous,
+ &ous);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ } else {
+ printf("Successfully queried joinable ous:\n");
+ for (i=0; i<num_ous; i++) {
+ printf("ou: %s\n", ous[i]);
+ }
+ }
+
+ out:
+ NetApiBufferFree(ous);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/getjoininformation.c b/source3/lib/netapi/examples/join/getjoininformation.c
new file mode 100644
index 0000000..7dac456
--- /dev/null
+++ b/source3/lib/netapi/examples/join/getjoininformation.c
@@ -0,0 +1,105 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Join Support (cmdline + netapi)
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *host_name = NULL;
+ char *name_buffer = NULL;
+ const char *p = NULL;
+ uint16_t name_type = 0;
+ struct libnetapi_ctx *ctx = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("getjoininformation", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ host_name = poptGetArg(pc);
+
+ /* NetGetJoinInformation */
+
+ status = NetGetJoinInformation(host_name, &p, &name_type);
+ name_buffer = discard_const_p(char, p);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ } else {
+ printf("Successfully queried join information:\n");
+
+ switch (name_type) {
+ case NetSetupUnknownStatus:
+ printf("%s's join status unknown (name: %s)\n",
+ host_name, name_buffer);
+ break;
+ case NetSetupUnjoined:
+ printf("%s is not joined (name: %s)\n",
+ host_name, name_buffer);
+ break;
+ case NetSetupWorkgroupName:
+ printf("%s is joined to workgroup %s\n",
+ host_name, name_buffer);
+ break;
+ case NetSetupDomainName:
+ printf("%s is joined to domain %s\n",
+ host_name, name_buffer);
+ break;
+ default:
+ printf("%s is in unknown status %d (name: %s)\n",
+ host_name, name_type, name_buffer);
+ break;
+ }
+ }
+
+ out:
+ NetApiBufferFree(name_buffer);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/netdomjoin.c b/source3/lib/netapi/examples/join/netdomjoin.c
new file mode 100644
index 0000000..08ce71b
--- /dev/null
+++ b/source3/lib/netapi/examples/join/netdomjoin.c
@@ -0,0 +1,104 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Join Support (cmdline + netapi)
+ * Copyright (C) Guenther Deschner 2007-2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+enum {
+ OPT_OU = 1000
+};
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *host_name = NULL;
+ const char *domain_name = NULL;
+ const char *account_ou = NULL;
+ const char *account = NULL;
+ const char *password = NULL;
+ uint32_t join_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_CREATE |
+ NETSETUP_DOMAIN_JOIN_IF_JOINED;
+ struct libnetapi_ctx *ctx = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "ou", 0, POPT_ARG_STRING, &account_ou, 'U', "Account ou", "ACCOUNT_OU" },
+ { "domain", 0, POPT_ARG_STRING, &domain_name, 'U', "Domain name (required)", "DOMAIN" },
+ { "userd", 0, POPT_ARG_STRING, &account, 'U', "Domain admin account", "USERNAME" },
+ { "passwordd", 0, POPT_ARG_STRING, &password, 'U', "Domain admin password", "PASSWORD" },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("netdomjoin", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ host_name = poptGetArg(pc);
+
+ if (!domain_name) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ /* NetJoinDomain */
+
+ status = NetJoinDomain(host_name,
+ domain_name,
+ account_ou,
+ account,
+ password,
+ join_flags);
+ if (status != 0) {
+ const char *errstr = NULL;
+ errstr = libnetapi_get_error_string(ctx, status);
+ printf("Join failed with: %s\n", errstr);
+ } else {
+ printf("Successfully joined\n");
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/provision_computer_account.c b/source3/lib/netapi/examples/join/provision_computer_account.c
new file mode 100644
index 0000000..cc2dde5
--- /dev/null
+++ b/source3/lib/netapi/examples/join/provision_computer_account.c
@@ -0,0 +1,122 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetProvisionComputerAccount query
+ * Copyright (C) Guenther Deschner 2021
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *domain = NULL;
+ const char *machine_name = NULL;
+ const char *machine_account_ou = NULL;
+ const char *dcname = NULL;
+ uint32_t options = 0;
+ const char *provision_text_data = NULL;
+ int default_password = 0;
+ int print_blob = 0;
+ const char *savefile = NULL;
+ int reuse = 0;
+
+ struct libnetapi_ctx *ctx = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "dcname", 0, POPT_ARG_STRING, &dcname, 'D', "Domain Controller Name", "DCNAME" },
+ { "machine_account_ou", 0, POPT_ARG_STRING, &machine_account_ou, 'D', "LDAP DN for Machine Account OU", "MACHINE_ACCOUNT_OU" },
+ { "defpwd", 0, POPT_ARG_NONE, &default_password, 'D', "Use default password for machine account (not recommended)", "" },
+ { "printblob", 0, POPT_ARG_NONE, &print_blob, 'D', "Print base64 encoded ODJ blob (for Windows answer files)", "" },
+ { "savefile", 0, POPT_ARG_STRING, &savefile, 'D', "Save ODJ blob to file (for Windows answer files)", "FILENAME" },
+ { "reuse", 0, POPT_ARG_NONE, &reuse, 'D', "Reuse machine account", "" },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("provision_computer_account", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "domain machine_name");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ domain = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ machine_name = poptGetArg(pc);
+
+ if (default_password) {
+ options |= NETSETUP_PROVISION_USE_DEFAULT_PASSWORD;
+ }
+ if (reuse) {
+ options |= NETSETUP_PROVISION_REUSE_ACCOUNT;
+ }
+
+ /* NetProvisionComputerAccount */
+
+ status = NetProvisionComputerAccount(domain,
+ machine_name,
+ machine_account_ou,
+ dcname,
+ options,
+ NULL,
+ 0,
+ &provision_text_data);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ if (print_blob) {
+ printf("Provision data: %s\n", provision_text_data);
+ }
+
+ if (savefile != NULL) {
+ status = netapi_save_file_ucs2(savefile, provision_text_data);
+ if (status != 0) {
+ goto out;
+ }
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/rename_machine.c b/source3/lib/netapi/examples/join/rename_machine.c
new file mode 100644
index 0000000..7be6dc2
--- /dev/null
+++ b/source3/lib/netapi/examples/join/rename_machine.c
@@ -0,0 +1,101 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetRenameMachineInDomain query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *host_name = NULL;
+ const char *new_machine_name = NULL;
+ uint32_t rename_opt = 0;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *username = NULL;
+ const char *password = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("rename_machine", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname newmachinename");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ host_name = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ new_machine_name = poptGetArg(pc);
+
+ /* NetRenameMachineInDomain */
+
+ status = libnetapi_get_username(ctx, &username);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+ status = libnetapi_get_password(ctx, &password);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ status = NetRenameMachineInDomain(host_name,
+ new_machine_name,
+ username,
+ password,
+ rename_opt);
+ if (status != 0) {
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/join/request_offline_domain_join.c b/source3/lib/netapi/examples/join/request_offline_domain_join.c
new file mode 100644
index 0000000..96bbe0b
--- /dev/null
+++ b/source3/lib/netapi/examples/join/request_offline_domain_join.c
@@ -0,0 +1,97 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetRequestOfflineDomainJoin
+ * Copyright (C) Guenther Deschner 2021
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ const char *windows_path = NULL;
+ uint32_t options = 0;
+ uint8_t *provision_bin_data = NULL;
+ uint32_t provision_bin_data_size = 0;
+ const char *loadfile = NULL;
+ struct libnetapi_ctx *ctx = NULL;
+ int localos = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "loadfile", 0, POPT_ARG_STRING, &loadfile, 'D', "Load file from previous provision", "FILENAME" },
+ { "localos", 0, POPT_ARG_NONE, &localos, 'D', "Request local OS to load offline join information", "" },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("request_offline_domain_join", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (loadfile == NULL) {
+ printf("--loadfile <FILENAME> is required\n");
+ goto out;
+ }
+ provision_bin_data = (uint8_t *)netapi_read_file(loadfile,
+ &provision_bin_data_size);
+ if (provision_bin_data == NULL) {
+ printf("failed to read loadfile: %s\n", loadfile);
+ goto out;
+ }
+
+ if (localos) {
+ options |= NETSETUP_PROVISION_ONLINE_CALLER;
+ }
+
+ /* NetRequestOfflineDomainJoin */
+
+ status = NetRequestOfflineDomainJoin(provision_bin_data,
+ provision_bin_data_size,
+ options,
+ windows_path);
+ free(provision_bin_data);
+ if (status != 0 && status != 0x00000a99) {
+ /* NERR_JoinPerformedMustRestart */
+ printf("failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_add.c b/source3/lib/netapi/examples/localgroup/localgroup_add.c
new file mode 100644
index 0000000..7f23c99
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_add.c
@@ -0,0 +1,106 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupAdd query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ const char *comment = NULL;
+ struct LOCALGROUP_INFO_0 g0;
+ struct LOCALGROUP_INFO_1 g1;
+ uint32_t parm_error = 0;
+ uint8_t *buf = NULL;
+ uint32_t level = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_add", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname comment");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ comment = poptGetArg(pc);
+ }
+
+ /* NetLocalGroupAdd */
+
+ if (comment) {
+ level = 1;
+ g1.lgrpi1_name = groupname;
+ g1.lgrpi1_comment = comment;
+ buf = (uint8_t *)&g1;
+ } else {
+ level = 0;
+ g0.lgrpi0_name = groupname;
+ buf = (uint8_t *)&g0;
+ }
+
+ status = NetLocalGroupAdd(hostname,
+ level,
+ buf,
+ &parm_error);
+ if (status != 0) {
+ printf("NetLocalGroupAdd failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_addmembers.c b/source3/lib/netapi/examples/localgroup/localgroup_addmembers.c
new file mode 100644
index 0000000..aa4a9b5
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_addmembers.c
@@ -0,0 +1,141 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupAddMembers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_0 *g0;
+ struct LOCALGROUP_MEMBERS_INFO_3 *g3;
+ uint32_t total_entries = 0;
+ uint8_t *buffer = NULL;
+ uint32_t level = 3;
+ const char **names = NULL;
+ int i = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_addmembers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname member1 member2 ...");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ names = poptGetArgs(pc);
+ for (i=0; names[i] != NULL; i++) {
+ total_entries++;
+ }
+
+ switch (level) {
+ case 0:
+ status = NetApiBufferAllocate(sizeof(struct LOCALGROUP_MEMBERS_INFO_0) * total_entries,
+ (void **)&g0);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ if (!ConvertStringSidToSid(names[i], &g0[i].lgrmi0_sid)) {
+ printf("could not convert sid\n");
+ goto out;
+ }
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 3:
+ status = NetApiBufferAllocate(sizeof(struct LOCALGROUP_MEMBERS_INFO_3) * total_entries,
+ (void **)&g3);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ g3[i].lgrmi3_domainandname = names[i];
+ }
+
+ buffer = (uint8_t *)g3;
+ break;
+ default:
+ break;
+ }
+
+ /* NetLocalGroupAddMembers */
+
+ status = NetLocalGroupAddMembers(hostname,
+ groupname,
+ level,
+ buffer,
+ total_entries);
+ if (status != 0) {
+ printf("NetLocalGroupAddMembers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_del.c b/source3/lib/netapi/examples/localgroup/localgroup_del.c
new file mode 100644
index 0000000..a2515df
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_del.c
@@ -0,0 +1,83 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupDel query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_del", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ /* NetLocalGroupDel */
+
+ status = NetLocalGroupDel(hostname,
+ groupname);
+ if (status != 0) {
+ printf("NetLocalGroupDel failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_delmembers.c b/source3/lib/netapi/examples/localgroup/localgroup_delmembers.c
new file mode 100644
index 0000000..7bd3ec0
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_delmembers.c
@@ -0,0 +1,141 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupDelMembers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_0 *g0;
+ struct LOCALGROUP_MEMBERS_INFO_3 *g3;
+ uint32_t total_entries = 0;
+ uint8_t *buffer = NULL;
+ uint32_t level = 3;
+ const char **names = NULL;
+ int i = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_delmembers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname member1 member2 ...");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ names = poptGetArgs(pc);
+ for (i=0; names[i] != NULL; i++) {
+ total_entries++;
+ }
+
+ switch (level) {
+ case 0:
+ status = NetApiBufferAllocate(sizeof(struct LOCALGROUP_MEMBERS_INFO_0) * total_entries,
+ (void **)&g0);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ if (!ConvertStringSidToSid(names[i], &g0[i].lgrmi0_sid)) {
+ printf("could not convert sid\n");
+ goto out;
+ }
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 3:
+ status = NetApiBufferAllocate(sizeof(struct LOCALGROUP_MEMBERS_INFO_3) * total_entries,
+ (void **)&g3);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ g3[i].lgrmi3_domainandname = names[i];
+ }
+
+ buffer = (uint8_t *)g3;
+ break;
+ default:
+ break;
+ }
+
+ /* NetLocalGroupDelMembers */
+
+ status = NetLocalGroupDelMembers(hostname,
+ groupname,
+ level,
+ buffer,
+ total_entries);
+ if (status != 0) {
+ printf("NetLocalGroupDelMembers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_enum.c b/source3/lib/netapi/examples/localgroup/localgroup_enum.c
new file mode 100644
index 0000000..6fe0cf4
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_enum.c
@@ -0,0 +1,126 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupEnum query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int i;
+
+ struct LOCALGROUP_INFO_0 *info0 = NULL;
+ struct LOCALGROUP_INFO_1 *info1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_enum", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetLocalGroupEnum */
+
+ do {
+ status = NetLocalGroupEnum(hostname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 0:
+ info0 = (struct LOCALGROUP_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct LOCALGROUP_INFO_1 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d group: %s\n", i, info0->lgrpi0_name);
+ info0++;
+ break;
+ case 1:
+ printf("#%d group: %s\n", i, info1->lgrpi1_name);
+ printf("#%d comment: %s\n", i, info1->lgrpi1_comment);
+ info1++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetLocalGroupEnum failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_getinfo.c b/source3/lib/netapi/examples/localgroup/localgroup_getinfo.c
new file mode 100644
index 0000000..cd8fa8c
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_getinfo.c
@@ -0,0 +1,112 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ struct LOCALGROUP_INFO_0 *g0;
+ struct LOCALGROUP_INFO_1 *g1;
+ struct LOCALGROUP_INFO_1002 *g1002;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetLocalGroupGetInfo */
+
+ status = NetLocalGroupGetInfo(hostname,
+ groupname,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetLocalGroupGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 0:
+ g0 = (struct LOCALGROUP_INFO_0 *)buffer;
+ printf("name: %s\n", g0->lgrpi0_name);
+ break;
+ case 1:
+ g1 = (struct LOCALGROUP_INFO_1 *)buffer;
+ printf("name: %s\n", g1->lgrpi1_name);
+ printf("comment: %s\n", g1->lgrpi1_comment);
+ break;
+ case 1002:
+ g1002 = (struct LOCALGROUP_INFO_1002 *)buffer;
+ printf("comment: %s\n", g1002->lgrpi1002_comment);
+ break;
+ }
+ NetApiBufferFree(buffer);
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_getmembers.c b/source3/lib/netapi/examples/localgroup/localgroup_getmembers.c
new file mode 100644
index 0000000..0589870
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_getmembers.c
@@ -0,0 +1,165 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupGetMembers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ char *sid_str = NULL;
+ int i;
+
+ struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_1 *info1 = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_2 *info2 = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_getmembers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetLocalGroupGetMembers */
+
+ do {
+ status = NetLocalGroupGetMembers(hostname,
+ groupname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 0:
+ info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct LOCALGROUP_MEMBERS_INFO_1 *)buffer;
+ break;
+ case 2:
+ info2 = (struct LOCALGROUP_MEMBERS_INFO_2 *)buffer;
+ break;
+ case 3:
+ info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ if (ConvertSidToStringSid(info0->lgrmi0_sid,
+ &sid_str)) {
+ printf("#%d member sid: %s\n", i, sid_str);
+ free(sid_str);
+ }
+ info0++;
+ break;
+ case 1:
+ if (ConvertSidToStringSid(info1->lgrmi1_sid,
+ &sid_str)) {
+ printf("#%d member sid: %s\n", i, sid_str);
+ free(sid_str);
+ }
+ printf("#%d sid type: %d\n", i, info1->lgrmi1_sidusage);
+ printf("#%d name: %s\n", i, info1->lgrmi1_name);
+ info1++;
+ break;
+ case 2:
+ if (ConvertSidToStringSid(info2->lgrmi2_sid,
+ &sid_str)) {
+ printf("#%d member sid: %s\n", i, sid_str);
+ free(sid_str);
+ }
+ printf("#%d sid type: %d\n", i, info2->lgrmi2_sidusage);
+ printf("#%d full name: %s\n", i, info2->lgrmi2_domainandname);
+ info2++;
+ break;
+ case 3:
+ printf("#%d full name: %s\n", i, info3->lgrmi3_domainandname);
+ info3++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetLocalGroupGetMembers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_setinfo.c b/source3/lib/netapi/examples/localgroup/localgroup_setinfo.c
new file mode 100644
index 0000000..efcec76
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_setinfo.c
@@ -0,0 +1,128 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupSetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ struct LOCALGROUP_INFO_0 g0;
+ struct LOCALGROUP_INFO_1 g1;
+ struct LOCALGROUP_INFO_1002 g1002;
+ const char *newname = NULL;
+ const char *newcomment = NULL;
+ uint32_t parm_err = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ { "newname", 0, POPT_ARG_STRING, NULL, 'n', "New Local Group Name", "NEWNAME" },
+ { "newcomment", 0, POPT_ARG_STRING, NULL, 'c', "New Local Group Comment", "NETCOMMENT" },
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_setinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ case 'n':
+ newname = poptGetOptArg(pc);
+ break;
+ case 'c':
+ newcomment = poptGetOptArg(pc);
+ break;
+ }
+
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ if (newname && !newcomment) {
+ g0.lgrpi0_name = newname;
+ buffer = (uint8_t *)&g0;
+ level = 0;
+ } else if (newcomment && !newname) {
+ g1002.lgrpi1002_comment = newcomment;
+ buffer = (uint8_t *)&g1002;
+ level = 1002;
+ } else if (newname && newcomment) {
+ g1.lgrpi1_name = newname;
+ g1.lgrpi1_comment = newcomment;
+ buffer = (uint8_t *)&g1;
+ level = 1;
+ } else {
+ printf("not enough input\n");
+ goto out;
+ }
+
+ /* NetLocalGroupSetInfo */
+
+ status = NetLocalGroupSetInfo(hostname,
+ groupname,
+ level,
+ buffer,
+ &parm_err);
+ if (status != 0) {
+ printf("NetLocalGroupSetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/localgroup/localgroup_setmembers.c b/source3/lib/netapi/examples/localgroup/localgroup_setmembers.c
new file mode 100644
index 0000000..c35f2bb
--- /dev/null
+++ b/source3/lib/netapi/examples/localgroup/localgroup_setmembers.c
@@ -0,0 +1,146 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetLocalGroupSetMembers query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *groupname = NULL;
+ struct LOCALGROUP_MEMBERS_INFO_0 *g0;
+ struct LOCALGROUP_MEMBERS_INFO_3 *g3;
+ uint32_t total_entries = 0;
+ uint8_t *buffer = NULL;
+ uint32_t level = 3;
+ const char **names = NULL;
+ int i = 0;
+ size_t buf_size = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("localgroup_setmembers", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname groupname member1 member2 ...");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ groupname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ names = poptGetArgs(pc);
+ for (i=0; names[i] != NULL; i++) {
+ total_entries++;
+ }
+
+ switch (level) {
+ case 0:
+ buf_size = sizeof(struct LOCALGROUP_MEMBERS_INFO_0) * total_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g0);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ if (!ConvertStringSidToSid(names[i], &g0[i].lgrmi0_sid)) {
+ printf("could not convert sid\n");
+ goto out;
+ }
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 3:
+ buf_size = sizeof(struct LOCALGROUP_MEMBERS_INFO_3) * total_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g3);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<total_entries; i++) {
+ g3[i].lgrmi3_domainandname = names[i];
+ }
+
+ buffer = (uint8_t *)g3;
+ break;
+ default:
+ break;
+ }
+
+ /* NetLocalGroupSetMembers */
+
+ status = NetLocalGroupSetMembers(hostname,
+ groupname,
+ level,
+ buffer,
+ total_entries);
+ if (status != 0) {
+ printf("NetLocalGroupSetMembers failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ NetApiBufferFree(buffer);
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
new file mode 100644
index 0000000..f041198
--- /dev/null
+++ b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
Binary files differ
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/logo.png b/source3/lib/netapi/examples/netdomjoin-gui/logo.png
new file mode 100644
index 0000000..6df4ace
--- /dev/null
+++ b/source3/lib/netapi/examples/netdomjoin-gui/logo.png
Binary files differ
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
new file mode 100644
index 0000000..ca599d3
--- /dev/null
+++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c
@@ -0,0 +1,1888 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Join Support (gtk + netapi)
+ * Copyright (C) Guenther Deschner 2007-2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <netdb.h>
+
+#include <gtk/gtk.h>
+#include <glib/gprintf.h>
+
+#include <netapi.h>
+
+#define MAX_CRED_LEN 256
+#define MAX_NETBIOS_NAME_LEN 15
+
+#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico"
+#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png"
+#define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png"
+
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+
+static gboolean verbose = FALSE;
+
+typedef struct join_state {
+ struct libnetapi_ctx *ctx;
+ GtkWidget *window_main;
+ GtkWidget *window_parent;
+ GtkWidget *window_do_change;
+ GtkWidget *window_creds_prompt;
+ GtkWidget *entry_account;
+ GtkWidget *entry_password;
+ GtkWidget *entry_domain;
+ GtkWidget *entry_ou_list;
+ GtkWidget *entry_workgroup;
+ GtkWidget *button_ok;
+ GtkWidget *button_apply;
+ GtkWidget *button_ok_creds;
+ GtkWidget *button_get_ous;
+ GtkWidget *label_reboot;
+ GtkWidget *label_current_name_buffer;
+ GtkWidget *label_current_name_type;
+ GtkWidget *label_full_computer_name;
+ GtkWidget *label_winbind;
+ uint16_t name_type_initial;
+ uint16_t name_type_new;
+ char *name_buffer_initial;
+ char *name_buffer_new;
+ char *password;
+ char *account;
+ char *comment;
+ char *comment_new;
+ char *my_fqdn;
+ char *my_dnsdomain;
+ char *my_hostname;
+ uint16_t server_role;
+ gboolean settings_changed;
+ gboolean hostname_changed;
+ uint32_t stored_num_ous;
+ char *target_hostname;
+ uid_t uid;
+} join_state;
+
+static void callback_creds_prompt(GtkWidget *widget,
+ gpointer data,
+ const char *label_string,
+ gpointer cont_fn);
+
+
+static void debug(const char *format, ...)
+{
+ va_list args;
+
+ if (!verbose) {
+ return;
+ }
+
+ va_start(args, format);
+ g_vprintf(format, args);
+ va_end(args);
+}
+
+static gboolean callback_delete_event(GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ gtk_main_quit();
+ return FALSE;
+}
+
+static void callback_do_close_data(GtkWidget *widget,
+ gpointer data)
+{
+ debug("callback_do_close_data called\n");
+
+ if (data) {
+ gtk_widget_destroy(GTK_WIDGET(data));
+ }
+}
+
+static void callback_do_close_widget(GtkWidget *widget,
+ gpointer data)
+{
+ debug("callback_do_close_widget called\n");
+
+ if (widget) {
+ gtk_widget_destroy(widget);
+ }
+}
+
+static void callback_do_freeauth(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_freeauth called\n");
+
+ SAFE_FREE(state->account);
+ SAFE_FREE(state->password);
+
+ if (state->window_creds_prompt) {
+ gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
+ state->window_creds_prompt = NULL;
+ }
+}
+
+static void callback_do_freeauth_and_close(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_freeauth_and_close called\n");
+
+ SAFE_FREE(state->account);
+ SAFE_FREE(state->password);
+
+ if (state->window_creds_prompt) {
+ gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
+ state->window_creds_prompt = NULL;
+ }
+ if (state->window_do_change) {
+ gtk_widget_destroy(GTK_WIDGET(state->window_do_change));
+ state->window_do_change = NULL;
+ }
+}
+
+static void free_join_state(struct join_state *s)
+{
+ SAFE_FREE(s->name_buffer_initial);
+ SAFE_FREE(s->name_buffer_new);
+ SAFE_FREE(s->password);
+ SAFE_FREE(s->account);
+ SAFE_FREE(s->comment);
+ SAFE_FREE(s->comment_new);
+ SAFE_FREE(s->my_fqdn);
+ SAFE_FREE(s->my_dnsdomain);
+ SAFE_FREE(s->my_hostname);
+}
+
+static void do_cleanup(struct join_state *state)
+{
+ libnetapi_free(state->ctx);
+ free_join_state(state);
+}
+
+static void callback_apply_description_change(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+ NET_API_STATUS status = 0;
+ uint32_t parm_err = 0;
+ struct SERVER_INFO_1005 info1005;
+ GtkWidget *dialog;
+
+ info1005.sv1005_comment = state->comment_new;
+
+ status = NetServerSetInfo(state->target_hostname,
+ 1005,
+ (uint8_t *)&info1005,
+ &parm_err);
+ if (status) {
+ debug("NetServerSetInfo failed with: %s\n",
+ libnetapi_errstr(status));
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "Failed to change computer description: %s.",
+ libnetapi_get_error_string(state->ctx, status));
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_main));
+
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show(dialog);
+ return;
+ }
+
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE);
+}
+
+static void callback_do_exit(GtkWidget *widget,
+ gpointer data)
+{
+#if 0
+ GtkWidget *dialog;
+ gint result;
+#endif
+ struct join_state *state = (struct join_state *)data;
+
+ if (!state->settings_changed) {
+ callback_delete_event(NULL, NULL, NULL);
+ return;
+ }
+
+#if 0
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO,
+ "You must restart your computer before the new settings will take effect.");
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+ switch (result) {
+ case GTK_RESPONSE_YES:
+ g_print("would reboot here\n");
+ break;
+ case GTK_RESPONSE_NO:
+ default:
+ break;
+ }
+ if (dialog) {
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ }
+#endif
+ if (state->window_main) {
+ gtk_widget_destroy(GTK_WIDGET(state->window_main));
+ state->window_main = NULL;
+ }
+ do_cleanup(state);
+ exit(0);
+}
+
+
+static void callback_do_reboot(GtkWidget *widget,
+ gpointer data,
+ gpointer data2)
+{
+ GtkWidget *dialog;
+ struct join_state *state = (struct join_state *)data2;
+
+ debug("callback_do_reboot\n");
+
+ state->settings_changed = TRUE;
+ dialog = gtk_message_dialog_new(GTK_WINDOW(data),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "You must restart this computer for the changes to take effect.");
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+#if 0
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ debug("showing dialog\n");
+ gtk_widget_show(dialog);
+#else
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+#endif
+
+ gtk_label_set_text(GTK_LABEL(state->label_reboot),
+ "Changes will take effect after you restart this computer");
+
+ debug("destroying do_change window\n");
+ gtk_widget_destroy(GTK_WIDGET(state->window_do_change));
+
+ {
+ uint32_t status;
+ const char *buffer;
+ uint16_t type;
+
+ status = NetGetJoinInformation(state->target_hostname,
+ &buffer,
+ &type);
+ if (status != 0) {
+ g_print("failed to query status\n");
+ return;
+ }
+
+ debug("got new status: %s\n", buffer);
+
+ SAFE_FREE(state->name_buffer_new);
+ state->name_buffer_new = strdup(buffer);
+ state->name_type_new = type;
+ state->name_buffer_initial = strdup(buffer);
+ state->name_type_initial = type;
+ NetApiBufferFree((void *)buffer);
+
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer),
+ state->name_buffer_new);
+ if (state->name_type_new == NetSetupDomainName) {
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
+ "Domain:");
+ } else {
+ gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
+ "Workgroup:");
+ }
+ }
+}
+
+static void callback_return_username(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text;
+ struct join_state *state = (struct join_state *)data;
+ debug("callback_return_username called\n");
+ if (!widget) {
+ return;
+ }
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if (!entry_text) {
+ return;
+ }
+ debug("callback_return_username: %s\n", entry_text);
+ SAFE_FREE(state->account);
+ state->account = strdup(entry_text);
+}
+
+static void callback_return_username_and_enter(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text;
+ struct join_state *state = (struct join_state *)data;
+ if (!widget) {
+ return;
+ }
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if (!entry_text) {
+ return;
+ }
+ debug("callback_return_username_and_enter: %s\n", entry_text);
+ SAFE_FREE(state->account);
+ state->account = strdup(entry_text);
+ g_signal_emit_by_name(state->button_ok_creds, "clicked");
+}
+
+static void callback_return_password(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text;
+ struct join_state *state = (struct join_state *)data;
+ debug("callback_return_password called\n");
+ if (!widget) {
+ return;
+ }
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if (!entry_text) {
+ return;
+ }
+#ifdef DEBUG_PASSWORD
+ debug("callback_return_password: %s\n", entry_text);
+#else
+ debug("callback_return_password: (not printed)\n");
+#endif
+ SAFE_FREE(state->password);
+ state->password = strdup(entry_text);
+}
+
+static void callback_return_password_and_enter(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text;
+ struct join_state *state = (struct join_state *)data;
+ if (!widget) {
+ return;
+ }
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if (!entry_text) {
+ return;
+ }
+#ifdef DEBUG_PASSWORD
+ debug("callback_return_password_and_enter: %s\n", entry_text);
+#else
+ debug("callback_return_password_and_enter: (not printed)\n");
+#endif
+ SAFE_FREE(state->password);
+ state->password = strdup(entry_text);
+ g_signal_emit_by_name(state->button_ok_creds, "clicked");
+}
+
+static void callback_do_storeauth(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_storeauth called\n");
+
+ SAFE_FREE(state->account);
+ SAFE_FREE(state->password);
+
+ callback_return_username(state->entry_account, (gpointer)state);
+ callback_return_password(state->entry_password, (gpointer)state);
+
+ if (state->window_creds_prompt) {
+ gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
+ state->window_creds_prompt = NULL;
+ }
+}
+
+static void callback_continue(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+
+ gtk_widget_grab_focus(GTK_WIDGET(state->button_ok));
+ g_signal_emit_by_name(state->button_ok, "clicked");
+}
+
+static void callback_do_storeauth_and_continue(GtkWidget *widget,
+ gpointer data)
+{
+ callback_do_storeauth(widget, data);
+ callback_continue(NULL, data);
+}
+
+static void callback_do_storeauth_and_scan(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+ callback_do_storeauth(widget, data);
+ g_signal_emit_by_name(state->button_get_ous, "clicked");
+}
+
+static void callback_do_hostname_change(GtkWidget *widget,
+ gpointer data)
+{
+ GtkWidget *dialog;
+ const char *str = NULL;
+
+ struct join_state *state = (struct join_state *)data;
+
+ switch (state->name_type_initial) {
+ case NetSetupDomainName: {
+#if 0
+ NET_API_STATUS status;
+ const char *newname;
+ char *p = NULL;
+
+ newname = strdup(gtk_label_get_text(GTK_LABEL(state->label_full_computer_name)));
+ if (!newname) {
+ return;
+ }
+
+ p = strchr(newname, '.');
+ if (p) {
+ *p = '\0';
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_hostname_change: no creds yet\n");
+ callback_creds_prompt(NULL, state,
+ "Enter the name and password of an account with permission to change a computer name in a the domain.",
+ callback_do_storeauth_and_continue);
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_hostname_change: still no creds???\n");
+ return;
+ }
+
+ status = NetRenameMachineInDomain(state->target_hostname,
+ newname,
+ state->account,
+ state->password,
+ NETSETUP_ACCT_CREATE);
+ SAFE_FREE(newname);
+ /* we renamed the machine in the domain */
+ if (status == 0) {
+ return;
+ }
+ str = libnetapi_get_error_string(state->ctx, status);
+#else
+ str = "To be implemented: call NetRenameMachineInDomain\n";
+#endif
+ break;
+ }
+ case NetSetupWorkgroupName:
+ str = "To be implemented: call SetComputerNameEx\n";
+ break;
+ default:
+ break;
+ }
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s",str);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_main));
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+ gtk_widget_show(dialog);
+}
+
+static void callback_creds_prompt(GtkWidget *widget,
+ gpointer data,
+ const char *label_string,
+ gpointer cont_fn)
+{
+ GtkWidget *window;
+ GtkWidget *box1;
+ GtkWidget *bbox;
+ GtkWidget *button;
+ GtkWidget *label;
+
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_creds_prompt\n");
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_modal(GTK_WINDOW(window), TRUE);
+
+ gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+ gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280);
+ gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
+ gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(state->window_do_change));
+ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
+
+ g_signal_connect(G_OBJECT(window), "delete_event",
+ G_CALLBACK(callback_do_close_widget), NULL);
+
+ state->window_creds_prompt = window;
+ gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+
+ box1 = gtk_vbox_new(FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(window), box1);
+
+ label = gtk_label_new(label_string);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+
+ gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
+
+ gtk_widget_show(label);
+
+ /* USER NAME */
+ label = gtk_label_new("User name:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ state->entry_account = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN);
+ g_signal_connect(G_OBJECT(state->entry_account), "activate",
+ G_CALLBACK(callback_return_username_and_enter),
+ (gpointer)state);
+ gtk_editable_select_region(GTK_EDITABLE(state->entry_account),
+ 0, GTK_ENTRY(state->entry_account)->text_length);
+ gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0);
+ gtk_widget_show(state->entry_account);
+
+ /* PASSWORD */
+ label = gtk_label_new("Password:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ state->entry_password = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN);
+ gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE);
+ g_signal_connect(G_OBJECT(state->entry_password), "activate",
+ G_CALLBACK(callback_return_password_and_enter),
+ (gpointer)state);
+ gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE);
+ gtk_editable_select_region(GTK_EDITABLE(state->entry_password),
+ 0, GTK_ENTRY(state->entry_password)->text_length);
+ gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0);
+ gtk_widget_show(state->entry_password);
+
+ /* BUTTONS */
+ bbox = gtk_hbutton_box_new();
+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
+ gtk_container_add(GTK_CONTAINER(box1), bbox);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 10);
+
+ state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK);
+ gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds));
+ gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds);
+ g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked",
+ G_CALLBACK(cont_fn),
+ (gpointer)state);
+ gtk_widget_show(state->button_ok_creds);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(callback_do_freeauth),
+ (gpointer)state);
+ gtk_widget_show_all(window);
+}
+
+static void callback_do_join(GtkWidget *widget,
+ gpointer data)
+{
+ GtkWidget *dialog;
+
+ NET_API_STATUS status;
+ const char *err_str = NULL;
+ uint32_t join_flags = 0;
+ uint32_t unjoin_flags = 0;
+ gboolean domain_join = FALSE;
+ gboolean try_unjoin = FALSE;
+ gboolean join_creds_required = TRUE;
+ gboolean unjoin_creds_required = TRUE;
+ const char *new_workgroup_type = NULL;
+ const char *initial_workgroup_type = NULL;
+ const char *account_ou = NULL;
+
+ struct join_state *state = (struct join_state *)data;
+
+ if (state->hostname_changed) {
+ callback_do_hostname_change(NULL, state);
+ return;
+ }
+
+ switch (state->name_type_initial) {
+ case NetSetupWorkgroupName:
+ initial_workgroup_type = "workgroup";
+ break;
+ case NetSetupDomainName:
+ initial_workgroup_type = "domain";
+ break;
+ default:
+ break;
+ }
+
+ switch (state->name_type_new) {
+ case NetSetupWorkgroupName:
+ new_workgroup_type = "workgroup";
+ break;
+ case NetSetupDomainName:
+ new_workgroup_type = "domain";
+ break;
+ default:
+ break;
+ }
+
+ account_ou = gtk_combo_box_get_active_text(GTK_COMBO_BOX(state->entry_ou_list));
+ if (account_ou && strlen(account_ou) == 0) {
+ account_ou = NULL;
+ }
+
+ if ((state->name_type_initial != NetSetupDomainName) &&
+ (state->name_type_new != NetSetupDomainName)) {
+ join_creds_required = FALSE;
+ unjoin_creds_required = FALSE;
+ }
+
+ if (state->name_type_new == NetSetupDomainName) {
+ domain_join = TRUE;
+ join_creds_required = TRUE;
+ join_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_CREATE |
+ NETSETUP_DOMAIN_JOIN_IF_JOINED; /* for testing */
+ }
+
+ if ((state->name_type_initial == NetSetupDomainName) &&
+ (state->name_type_new == NetSetupWorkgroupName)) {
+ try_unjoin = TRUE;
+ unjoin_creds_required = TRUE;
+ join_creds_required = FALSE;
+ unjoin_flags = NETSETUP_JOIN_DOMAIN |
+ NETSETUP_ACCT_DELETE |
+ NETSETUP_IGNORE_UNSUPPORTED_FLAGS;
+ }
+
+ if (try_unjoin) {
+
+ debug("callback_do_join: Unjoining\n");
+
+ if (unjoin_creds_required) {
+ if (!state->account || !state->password) {
+ debug("callback_do_join: no creds yet\n");
+ callback_creds_prompt(NULL, state,
+ "Enter the name and password of an account with permission to leave the domain.",
+ callback_do_storeauth_and_continue);
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_join: still no creds???\n");
+ return;
+ }
+ }
+
+ status = NetUnjoinDomain(state->target_hostname,
+ state->account,
+ state->password,
+ unjoin_flags);
+ if (status != 0) {
+ callback_do_freeauth(NULL, state);
+ err_str = libnetapi_get_error_string(state->ctx, status);
+ g_print("callback_do_join: failed to unjoin (%s)\n",
+ err_str);
+#if 0
+
+ /* in fact we shouldn't annoy the user with an error message here */
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "The following error occurred attempting to unjoin the %s: \"%s\": %s",
+ initial_workgroup_type,
+ state->name_buffer_initial,
+ err_str);
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+#endif
+ }
+
+ }
+
+ /* before prompting for creds, make sure we can find a dc */
+
+ if (domain_join) {
+
+ struct DOMAIN_CONTROLLER_INFO *dc_info = NULL;
+
+ status = DsGetDcName(NULL,
+ state->name_buffer_new,
+ NULL,
+ NULL,
+ 0,
+ &dc_info);
+ if (status != 0) {
+ err_str = libnetapi_get_error_string(state->ctx, status);
+ g_print("callback_do_join: failed find dc (%s)\n", err_str);
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to find a domain controller for domain: \"%s\": %s",
+ state->name_buffer_new,
+ err_str);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show(dialog);
+
+ return;
+ }
+ }
+
+ if (join_creds_required) {
+ if (!state->account || !state->password) {
+ debug("callback_do_join: no creds yet\n");
+ callback_creds_prompt(NULL, state,
+ "Enter the name and password of an account with permission to join the domain.",
+ callback_do_storeauth_and_continue);
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_join: still no creds???\n");
+ return;
+ }
+ }
+
+ debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ",
+ new_workgroup_type,
+ state->name_buffer_new,
+ join_flags);
+ if (domain_join) {
+ debug("as %s ", state->account);
+#ifdef DEBUG_PASSWORD
+ debug("with %s ", state->password);
+#endif
+ }
+ debug("\n");
+
+ status = NetJoinDomain(state->target_hostname,
+ state->name_buffer_new,
+ account_ou,
+ state->account,
+ state->password,
+ join_flags);
+ if (status != 0) {
+ callback_do_freeauth(NULL, state);
+ err_str = libnetapi_get_error_string(state->ctx, status);
+ g_print("callback_do_join: failed to join (%s)\n", err_str);
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "The following error occurred attempting to join the %s: \"%s\": %s",
+ new_workgroup_type,
+ state->name_buffer_new,
+ err_str);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show(dialog);
+
+ return;
+ }
+
+ debug("callback_do_join: Successfully joined %s\n",
+ new_workgroup_type);
+
+ callback_do_freeauth(NULL, state);
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "Welcome to the %s %s.",
+ state->name_buffer_new,
+ new_workgroup_type);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+
+ callback_do_reboot(NULL, state->window_parent, state);
+}
+
+static void callback_enter_hostname_and_unlock(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text = NULL;
+ char *str = NULL;
+ struct join_state *state = (struct join_state *)data;
+
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ debug("callback_enter_hostname_and_unlock: %s\n", entry_text);
+ if (!entry_text || entry_text[0] == 0) {
+ state->hostname_changed = FALSE;
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), "");
+ return;
+ }
+ if (strcasecmp(state->my_hostname, entry_text) == 0) {
+ state->hostname_changed = FALSE;
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ /* return; */
+ } else {
+ state->hostname_changed = TRUE;
+ }
+
+ if (state->name_type_initial == NetSetupDomainName) {
+ if (asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain) == -1) {
+ return;
+ }
+ } else {
+ if (asprintf(&str, "%s.", entry_text) == -1) {
+ return;
+ }
+ }
+ gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str);
+ free(str);
+
+ if (state->hostname_changed && entry_text && entry_text[0] != 0 && entry_text[0] != '.') {
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
+ }
+}
+
+static void callback_enter_computer_description_and_unlock(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text = NULL;
+ struct join_state *state = (struct join_state *)data;
+ int string_unchanged = FALSE;
+
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ debug("callback_enter_computer_description_and_unlock: %s\n",
+ entry_text);
+#if 0
+ if (!entry_text || entry_text[0] == 0) {
+ string_unchanged = 1;
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply),
+ FALSE);
+ return;
+ }
+#endif
+ if (entry_text && state->comment && strcasecmp(state->comment, entry_text) == 0) {
+ string_unchanged = TRUE;
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply),
+ FALSE);
+ return;
+ }
+
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE);
+ SAFE_FREE(state->comment_new);
+ state->comment_new = strdup(entry_text);
+
+}
+
+
+static void callback_enter_workgroup_and_unlock(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text = NULL;
+ struct join_state *state = (struct join_state *)data;
+
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ debug("callback_enter_workgroup_and_unlock: %s\n", entry_text);
+ if (!entry_text || entry_text[0] == 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ return;
+ }
+ if ((strcasecmp(state->name_buffer_initial, entry_text) == 0) &&
+ (state->name_type_initial == NetSetupWorkgroupName)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
+ SAFE_FREE(state->name_buffer_new);
+ state->name_buffer_new = strdup(entry_text);
+ state->name_type_new = NetSetupWorkgroupName;
+}
+
+static void callback_enter_domain_and_unlock(GtkWidget *widget,
+ gpointer data)
+{
+ const gchar *entry_text = NULL;
+ struct join_state *state = (struct join_state *)data;
+
+ entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
+ debug("callback_enter_domain_and_unlock: %s\n", entry_text);
+ if (!entry_text || entry_text[0] == 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ return;
+ }
+ if ((strcasecmp(state->name_buffer_initial, entry_text) == 0) &&
+ (state->name_type_initial == NetSetupDomainName)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_ou_list), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_get_ous), TRUE);
+ SAFE_FREE(state->name_buffer_new);
+ state->name_buffer_new = strdup(entry_text);
+ state->name_type_new = NetSetupDomainName;
+}
+
+static void callback_apply_continue(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+
+ gtk_widget_grab_focus(GTK_WIDGET(state->button_apply));
+ g_signal_emit_by_name(state->button_apply, "clicked");
+}
+
+static void callback_do_join_workgroup(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+ debug("callback_do_join_workgroup choosen\n");
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
+ gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup));
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_ou_list), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_get_ous), FALSE);
+ callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */
+}
+
+static void callback_do_join_domain(GtkWidget *widget,
+ gpointer data)
+{
+ struct join_state *state = (struct join_state *)data;
+ debug("callback_do_join_domain choosen\n");
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE);
+ gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain));
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE);
+ callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */
+}
+
+static void callback_do_getous(GtkWidget *widget,
+ gpointer data)
+{
+ NET_API_STATUS status;
+ uint32_t num_ous = 0;
+ const char **ous = NULL;
+ int i;
+ const char *domain = NULL;
+ struct DOMAIN_CONTROLLER_INFO *dc_info = NULL;
+ const char *err_str = NULL;
+ GtkWidget *dialog;
+
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_getous called\n");
+
+ domain = state->name_buffer_new ? state->name_buffer_new : state->name_buffer_initial;
+
+ status = DsGetDcName(NULL,
+ domain,
+ NULL,
+ NULL,
+ 0,
+ &dc_info);
+ if (status != 0) {
+ err_str = libnetapi_get_error_string(state->ctx, status);
+ g_print("callback_do_getous: failed find dc (%s)\n", err_str);
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to find a domain controller for domain: \"%s\": %s",
+ domain,
+ err_str);
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show(dialog);
+
+ return;
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_getous: no creds yet\n");
+ callback_creds_prompt(NULL, state,
+ "Enter the name and password of an account with permission to join the domain.",
+ callback_do_storeauth_and_scan);
+ }
+
+ if (!state->account || !state->password) {
+ debug("callback_do_getous: still no creds ???\n");
+ return;
+ }
+
+ status = NetGetJoinableOUs(state->target_hostname,
+ domain,
+ state->account,
+ state->password,
+ &num_ous, &ous);
+ if (status != NET_API_STATUS_SUCCESS) {
+ callback_do_freeauth(NULL, state);
+ debug("failed to call NetGetJoinableOUs: %s\n",
+ libnetapi_get_error_string(state->ctx, status));
+ dialog = gtk_message_dialog_new(NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_OK,
+ "Failed to query joinable OUs: %s",
+ libnetapi_get_error_string(state->ctx, status));
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(state->window_do_change));
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+ return;
+ }
+
+ for (i=0; i<state->stored_num_ous; i++) {
+ gtk_combo_box_remove_text(GTK_COMBO_BOX(state->entry_ou_list), 0);
+ }
+ for (i=0; i<num_ous && ous[i] != NULL; i++) {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(state->entry_ou_list),
+ ous[i]);
+ }
+ NetApiBufferFree(ous);
+ state->stored_num_ous = num_ous;
+ gtk_combo_box_set_active(GTK_COMBO_BOX(state->entry_ou_list), num_ous-1);
+}
+
+static void callback_do_change(GtkWidget *widget,
+ gpointer data)
+{
+ GtkWidget *window;
+ GtkWidget *box1;
+ GtkWidget *bbox;
+ GtkWidget *button_workgroup;
+ GtkWidget *button_domain;
+ GtkWidget *button;
+ GtkWidget *label;
+ GtkWidget *frame_horz;
+ GtkWidget *vbox;
+ GtkWidget *entry;
+ GSList *group;
+
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_change called\n");
+
+#if 0
+ /* FIXME: add proper warnings for Samba as a DC */
+ if (state->server_role == 3) {
+ GtkWidget *dialog;
+ callback_do_freeauth(NULL, state);
+ dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK.");
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ g_signal_connect_swapped(dialog, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show(dialog);
+ return;
+ }
+#endif
+
+ state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
+ state->button_get_ous = gtk_button_new_with_label("Scan for joinable OUs");
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_modal(GTK_WINDOW(window), TRUE);
+
+ gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ gtk_widget_set_size_request(GTK_WIDGET(window), 480, 650);
+ gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
+ gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(state->window_main));
+ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
+
+ g_signal_connect(G_OBJECT(window), "delete_event",
+ G_CALLBACK(callback_do_close_widget), NULL);
+
+ gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+
+ box1 = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(window), box1);
+
+ label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network resources.");
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ /* COMPUTER NAME */
+ label = gtk_label_new("Computer name:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ state->label_full_computer_name = gtk_label_new(NULL);
+ {
+ entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN);
+ g_signal_connect(G_OBJECT(entry), "changed",
+ G_CALLBACK(callback_enter_hostname_and_unlock),
+ (gpointer)state);
+ gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname);
+ gtk_editable_select_region(GTK_EDITABLE(entry),
+ 0, GTK_ENTRY(entry)->text_length);
+
+ gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */
+ gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0);
+ gtk_widget_show(entry);
+ }
+
+ /* FULL COMPUTER NAME */
+ label = gtk_label_new("Full computer name:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ {
+ const gchar *entry_text;
+ char *str = NULL;
+ entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
+ if (state->name_type_initial == NetSetupDomainName) {
+ if (asprintf(&str, "%s.%s", entry_text,
+ state->my_dnsdomain) == -1) {
+ return;
+ }
+ } else {
+ if (asprintf(&str, "%s.", entry_text) == -1) {
+ return;
+ }
+ }
+ gtk_label_set_text(GTK_LABEL(state->label_full_computer_name),
+ str);
+ free(str);
+ gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0);
+ gtk_box_pack_start(GTK_BOX(box1),
+ state->label_full_computer_name, TRUE, TRUE, 0);
+ gtk_widget_show(state->label_full_computer_name);
+ }
+
+ /* BOX */
+ frame_horz = gtk_frame_new ("Member Of");
+ gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
+ gtk_container_add(GTK_CONTAINER(frame_horz), vbox);
+
+ /* TWO ENTRIES */
+ state->entry_workgroup = gtk_entry_new();
+ state->entry_domain = gtk_entry_new();
+
+ /* DOMAIN */
+ button_domain = gtk_radio_button_new_with_label(NULL, "Domain");
+ if (state->name_type_initial == NetSetupDomainName) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE);
+ }
+ gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(button_domain), "clicked",
+ G_CALLBACK(callback_do_join_domain),
+ (gpointer)state);
+
+ {
+ gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50);
+ g_signal_connect(G_OBJECT(state->entry_domain), "changed",
+ G_CALLBACK(callback_enter_domain_and_unlock),
+ (gpointer)state);
+ g_signal_connect(G_OBJECT(state->entry_domain), "activate",
+ G_CALLBACK(callback_continue),
+ (gpointer)state);
+ if (state->name_type_initial == NetSetupDomainName) {
+ gtk_entry_set_text(GTK_ENTRY(state->entry_domain),
+ state->name_buffer_initial);
+ gtk_widget_set_sensitive(state->entry_workgroup, FALSE);
+ gtk_widget_set_sensitive(state->entry_domain, TRUE);
+ }
+ gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE);
+ gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0);
+ gtk_widget_show(state->entry_domain);
+ }
+ gtk_widget_show(button_domain);
+
+ /* WORKGROUP */
+ group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain));
+ button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup");
+ if (state->name_type_initial == NetSetupWorkgroupName) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE);
+ }
+ gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(button_workgroup), "clicked",
+ G_CALLBACK(callback_do_join_workgroup),
+ (gpointer)state);
+ {
+ gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup),
+ MAX_NETBIOS_NAME_LEN);
+ g_signal_connect(G_OBJECT(state->entry_workgroup), "changed",
+ G_CALLBACK(callback_enter_workgroup_and_unlock),
+ (gpointer)state);
+ g_signal_connect(G_OBJECT(state->entry_workgroup), "activate",
+ G_CALLBACK(callback_continue),
+ (gpointer)state);
+
+ if (state->name_type_initial == NetSetupWorkgroupName) {
+ gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup),
+ state->name_buffer_initial);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
+ }
+ gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0);
+ gtk_widget_show(state->entry_workgroup);
+ }
+ gtk_widget_show(button_workgroup);
+
+ /* Advanced Options */
+ frame_horz = gtk_frame_new("Advanced Options");
+ gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
+ gtk_container_add(GTK_CONTAINER(frame_horz), vbox);
+
+ /* OUs */
+ gtk_container_add(GTK_CONTAINER(vbox), state->button_get_ous);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_get_ous), FALSE);
+ g_signal_connect(G_OBJECT(state->button_get_ous), "clicked",
+ G_CALLBACK(callback_do_getous),
+ (gpointer)state);
+
+ state->entry_ou_list = gtk_combo_box_entry_new_text();
+ gtk_widget_set_sensitive(state->entry_ou_list, FALSE);
+ if (state->name_type_initial == NetSetupWorkgroupName) {
+ gtk_widget_set_sensitive(state->entry_ou_list, FALSE);
+ gtk_widget_set_sensitive(state->button_get_ous, FALSE);
+ }
+ gtk_box_pack_start(GTK_BOX(vbox), state->entry_ou_list, TRUE, TRUE, 0);
+ gtk_widget_show(state->entry_ou_list);
+
+ {
+ state->label_winbind = gtk_check_button_new_with_label("Modify winbind configuration");
+ gtk_box_pack_start(GTK_BOX(vbox), state->label_winbind, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive(state->label_winbind, FALSE);
+ }
+
+
+ /* BUTTONS */
+ bbox = gtk_hbutton_box_new();
+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
+ gtk_container_add(GTK_CONTAINER(box1), bbox);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 10);
+
+ state->window_do_change = window;
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE);
+ gtk_container_add(GTK_CONTAINER(bbox), state->button_ok);
+ g_signal_connect(G_OBJECT(state->button_ok), "clicked",
+ G_CALLBACK(callback_do_join),
+ (gpointer)state);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(callback_do_freeauth_and_close),
+ (gpointer)state);
+
+ gtk_widget_show_all(window);
+}
+
+static void callback_do_about(GtkWidget *widget,
+ gpointer data)
+{
+ GdkPixbuf *logo;
+ GError *error = NULL;
+ GtkWidget *about;
+
+ struct join_state *state = (struct join_state *)data;
+
+ debug("callback_do_about called\n");
+
+ logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH,
+ &error);
+ if (logo == NULL) {
+ g_print("failed to load logo from %s: %s\n",
+ SAMBA_IMAGE_PATH, error->message);
+ }
+
+ about = gtk_about_dialog_new();
+ gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "Samba");
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), "3.2.0pre3");
+ gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about),
+ "Copyright Andrew Tridgell and the Samba Team 1992-2008\n"
+ "Copyright Günther Deschner 2007-2008");
+ gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about), "GPLv3");
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about), "http://www.samba.org");
+ gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about), "http://www.samba.org");
+ if (logo) {
+ gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about), logo);
+ }
+ gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about), "Samba gtk domain join utility");
+ gtk_window_set_modal(GTK_WINDOW(about), TRUE);
+ gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(state->window_main));
+ g_signal_connect_swapped(about, "response",
+ G_CALLBACK(gtk_widget_destroy),
+ about);
+
+ gtk_widget_show(about);
+}
+
+static int draw_main_window(struct join_state *state)
+{
+ GtkWidget *window;
+ GtkWidget *button;
+ GtkWidget *label;
+ GtkWidget *main_vbox;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *bbox;
+ GtkWidget *image;
+ GtkWidget *table;
+ GtkWidget *entry;
+ GdkPixbuf *icon;
+ GError *error = NULL;
+
+ icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH,
+ &error);
+ if (icon == NULL) {
+ g_print("failed to load icon from %s : %s\n",
+ SAMBA_ICON_PATH, error->message);
+ }
+
+#if 1
+ image = gtk_image_new_from_file(SAMBA_IMAGE_PATH_SMALL);
+#else
+ image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png");
+#endif
+ if (image == NULL) {
+ g_print("failed to load logo from %s : %s\n",
+ SAMBA_IMAGE_PATH_SMALL, error->message);
+ }
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ state->window_main = window;
+
+ gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue");
+ gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600);
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
+ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
+
+ g_signal_connect(G_OBJECT(window), "delete_event",
+ G_CALLBACK(callback_delete_event), NULL);
+
+ gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+
+ main_vbox = gtk_vbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(window), main_vbox);
+
+#if 0
+ gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10);
+ gtk_widget_show(image);
+#endif
+ /* Hbox */
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(main_vbox), hbox);
+
+ {
+/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */
+/* gtk_misc_set_alignment(GTK_MISC(image), 0, 0); */
+ gtk_widget_set_size_request(GTK_WIDGET(image), 150, 40);
+ gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10);
+ gtk_widget_show(image);
+
+ /* Label */
+ label = gtk_label_new("Samba uses the following information to identify your computer on the network.");
+/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */
+ gtk_widget_set_size_request(GTK_WIDGET(label), 400, 40);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+ }
+
+ gtk_widget_show(hbox);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
+ gtk_container_add(GTK_CONTAINER(main_vbox), vbox);
+
+ /* Table */
+ table = gtk_table_new(6, 3, TRUE);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 5);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+ gtk_container_add(GTK_CONTAINER(vbox), table);
+
+ {
+ /* Label */
+ label = gtk_label_new("Computer description:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
+ gtk_widget_show(label);
+
+ state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY);
+
+ /* Entry */
+ entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(entry), 256);
+
+ if (!state->target_hostname && state->uid != 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(entry), FALSE);
+ }
+ g_signal_connect(G_OBJECT(entry), "changed",
+ G_CALLBACK(callback_enter_computer_description_and_unlock),
+ state);
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(callback_apply_continue),
+ (gpointer)state);
+
+ gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment);
+ gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */
+ gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1);
+ gtk_widget_show(entry);
+ }
+
+ /* Label */
+ label = gtk_label_new("For example: \"Samba \%v\".");
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2);
+ gtk_widget_show(label);
+
+ /* Label */
+ label = gtk_label_new("Full computer name:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
+ gtk_widget_show(label);
+
+ {
+ /* Label */
+ char *str = NULL;
+ if (state->name_type_initial == NetSetupDomainName) {
+ if (asprintf(&str, "%s.%s", state->my_hostname,
+ state->my_dnsdomain) == -1) {
+ return -1;
+ }
+ } else {
+ if (asprintf(&str, "%s.", state->my_hostname) == -1) {
+ return -1;
+ }
+ }
+
+ label = gtk_label_new(str);
+ SAFE_FREE(str);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3);
+ gtk_widget_show(label);
+ }
+
+ /* Label */
+ if (state->name_type_initial == NetSetupDomainName) {
+ label = gtk_label_new("Domain:");
+ } else {
+ label = gtk_label_new("Workgroup:");
+ }
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
+ gtk_widget_show(label);
+ state->label_current_name_type = label;
+
+ /* Label */
+ label = gtk_label_new(state->name_buffer_initial);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4);
+ gtk_widget_show(label);
+ state->label_current_name_buffer = label;
+
+ {
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(vbox), hbox);
+ label = gtk_label_new("To rename this computer or join a domain, click Change.");
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+
+ }
+
+ /* bbox */
+ bbox = gtk_hbutton_box_new();
+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
+ gtk_container_add(GTK_CONTAINER(hbox), bbox);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox), 10);
+
+ button = gtk_button_new_with_mnemonic("Ch_ange");
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(callback_do_change),
+ (gpointer)state);
+ gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0);
+ if (!state->target_hostname && state->uid != 0) {
+ gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+ }
+ gtk_widget_show(button);
+
+ /* Label (hidden) */
+ state->label_reboot = gtk_label_new(NULL);
+ gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0);
+ if (!state->target_hostname && state->uid != 0) {
+ gtk_label_set_text(GTK_LABEL(state->label_reboot),
+ "You cannot change computer description as you're not running with root permissions");
+ }
+
+ gtk_widget_show(state->label_reboot);
+
+#if 0
+ gtk_box_pack_start(GTK_BOX(vbox),
+ create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END),
+ TRUE, TRUE, 5);
+#endif
+ {
+
+ GtkWidget *frame;
+ GtkWidget *bbox2;
+ GtkWidget *button2;
+
+ frame = gtk_frame_new(NULL);
+ bbox2 = gtk_hbutton_box_new();
+
+ gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5);
+ gtk_container_add(GTK_CONTAINER(frame), bbox2);
+
+ /* Set the appearance of the Button Box */
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(bbox2), 10);
+ /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/
+
+ button2 = gtk_button_new_from_stock(GTK_STOCK_OK);
+ gtk_container_add(GTK_CONTAINER(bbox2), button2);
+ g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state);
+
+ button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ gtk_container_add(GTK_CONTAINER(bbox2), button2);
+ g_signal_connect(G_OBJECT(button2), "clicked",
+ G_CALLBACK(callback_delete_event),
+ window);
+
+ gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply);
+ g_signal_connect(G_OBJECT(state->button_apply), "clicked",
+ G_CALLBACK(callback_apply_description_change),
+ state);
+ gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE);
+
+ button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT);
+ gtk_container_add(GTK_CONTAINER(bbox2), button2);
+ g_signal_connect(G_OBJECT(button2), "clicked",
+ G_CALLBACK(callback_do_about),
+ state);
+#if 0
+ button2 = gtk_button_new_from_stock(GTK_STOCK_HELP);
+ gtk_container_add(GTK_CONTAINER(bbox2), button2);
+ g_signal_connect(G_OBJECT(button2), "clicked",
+ G_CALLBACK(callback_do_about),
+ window);
+#endif
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5);
+ }
+
+ gtk_widget_show_all(window);
+
+ return 0;
+}
+
+static int init_join_state(struct join_state **state)
+{
+ struct join_state *s;
+
+ s = (struct join_state *)malloc(sizeof(struct join_state));
+ if (!s) {
+ return -1;
+ }
+
+ memset(s, '\0', sizeof(struct join_state));
+
+ *state = s;
+
+ return 0;
+}
+
+static NET_API_STATUS get_server_properties(struct join_state *state)
+{
+ struct SERVER_INFO_101 *info101 = NULL;
+ struct SERVER_INFO_1005 *info1005 = NULL;
+ NET_API_STATUS status;
+
+ status = NetServerGetInfo(state->target_hostname,
+ 101,
+ (uint8_t **)&info101);
+ if (status == 0) {
+ state->comment = strdup(info101->sv101_comment);
+ if (!state->comment) {
+ return -1;
+ }
+ SAFE_FREE(state->my_hostname);
+ state->my_hostname = strdup(info101->sv101_name);
+ if (!state->my_hostname) {
+ return -1;
+ }
+ NetApiBufferFree(info101);
+ return NET_API_STATUS_SUCCESS;
+ }
+
+ switch (status) {
+ case 124: /* WERR_INVALID_LEVEL */
+ case 50: /* WERR_NOT_SUPPORTED */
+ break;
+ default:
+ goto failed;
+ }
+
+ status = NetServerGetInfo(state->target_hostname,
+ 1005,
+ (uint8_t **)&info1005);
+ if (status == 0) {
+ state->comment = strdup(info1005->sv1005_comment);
+ if (!state->comment) {
+ return -1;
+ }
+ NetApiBufferFree(info1005);
+ return NET_API_STATUS_SUCCESS;
+ }
+
+ failed:
+ printf("NetServerGetInfo failed with: %s\n",
+ libnetapi_get_error_string(state->ctx, status));
+
+ return status;
+}
+
+static int initialize_join_state(struct join_state *state,
+ const char *debug_level,
+ const char *target_hostname,
+ const char *target_username)
+{
+ struct libnetapi_ctx *ctx = NULL;
+ NET_API_STATUS status = 0;
+
+ status = libnetapi_init(&ctx);
+ if (status) {
+ return status;
+ }
+
+ if (debug_level) {
+ libnetapi_set_debuglevel(ctx, debug_level);
+ }
+
+ if (target_hostname) {
+ state->target_hostname = strdup(target_hostname);
+ if (!state->target_hostname) {
+ return -1;
+ }
+ }
+
+ if (target_username) {
+ char *puser = strdup(target_username);
+ char *p = NULL;
+
+ if ((p = strchr(puser,'%'))) {
+ size_t len;
+ *p = 0;
+ libnetapi_set_username(ctx, puser);
+ libnetapi_set_password(ctx, p+1);
+ len = strlen(p+1);
+ memset(strchr(target_username,'%')+1,'X',len);
+ } else {
+ libnetapi_set_username(ctx, puser);
+ }
+ free(puser);
+ }
+
+ {
+ char my_hostname[HOST_NAME_MAX];
+ const char *p = NULL;
+ struct hostent *hp = NULL;
+
+ if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
+ return -1;
+ }
+
+ p = strchr(my_hostname, '.');
+ if (p) {
+ my_hostname[strlen(my_hostname)-strlen(p)] = '\0';
+ }
+ state->my_hostname = strdup(my_hostname);
+ if (!state->my_hostname) {
+ return -1;
+ }
+ debug("state->my_hostname: %s\n", state->my_hostname);
+
+ hp = gethostbyname(my_hostname);
+ if (!hp || !hp->h_name || !*hp->h_name) {
+ return -1;
+ }
+
+ state->my_fqdn = strdup(hp->h_name);
+ if (!state->my_fqdn) {
+ return -1;
+ }
+ debug("state->my_fqdn: %s\n", state->my_fqdn);
+
+ p = strchr(state->my_fqdn, '.');
+ if (p) {
+ p++;
+ state->my_dnsdomain = strdup(p);
+ } else {
+ state->my_dnsdomain = strdup("");
+ }
+ if (!state->my_dnsdomain) {
+ return -1;
+ }
+ debug("state->my_dnsdomain: %s\n", state->my_dnsdomain);
+ }
+
+ {
+ const char *buffer = NULL;
+ uint16_t type = 0;
+ status = NetGetJoinInformation(state->target_hostname,
+ &buffer,
+ &type);
+ if (status != 0) {
+ printf("NetGetJoinInformation failed with: %s\n",
+ libnetapi_get_error_string(state->ctx, status));
+ return status;
+ }
+ debug("NetGetJoinInformation gave: %s and %d\n", buffer, type);
+ state->name_buffer_initial = strdup(buffer);
+ if (!state->name_buffer_initial) {
+ return -1;
+ }
+ state->name_type_initial = type;
+ NetApiBufferFree((void *)buffer);
+ }
+
+ status = get_server_properties(state);
+ if (status != 0) {
+ return -1;
+ }
+
+ state->uid = geteuid();
+
+ state->ctx = ctx;
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ GOptionContext *context = NULL;
+ static const char *debug_level = NULL;
+ static const char *target_hostname = NULL;
+ static const char *target_username = NULL;
+ struct join_state *state = NULL;
+ GError *error = NULL;
+ int ret = 0;
+
+ static GOptionEntry entries[] = {
+ { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" },
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 },
+ { "target", 'S', 0, G_OPTION_ARG_STRING, &target_hostname, "Target hostname", 0 },
+ { "username", 'U', 0, G_OPTION_ARG_STRING, &target_username, "Target hostname", 0 },
+ { NULL }
+ };
+
+ context = g_option_context_new("- Samba domain join utility");
+ g_option_context_add_main_entries(context, entries, NULL);
+/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+ g_option_context_parse(context, &argc, &argv, &error);
+
+ gtk_init(&argc, &argv);
+ g_set_application_name("Samba");
+
+ ret = init_join_state(&state);
+ if (ret) {
+ return ret;
+ }
+
+ ret = initialize_join_state(state, debug_level,
+ target_hostname,
+ target_username);
+ if (ret) {
+ return ret;
+ }
+
+ draw_main_window(state);
+
+ gtk_main();
+
+ do_cleanup(state);
+
+ return 0;
+}
diff --git a/source3/lib/netapi/examples/netdomjoin-gui/samba.ico b/source3/lib/netapi/examples/netdomjoin-gui/samba.ico
new file mode 100755
index 0000000..b70c959
--- /dev/null
+++ b/source3/lib/netapi/examples/netdomjoin-gui/samba.ico
Binary files differ
diff --git a/source3/lib/netapi/examples/netlogon/netlogon_control.c b/source3/lib/netapi/examples/netlogon/netlogon_control.c
new file mode 100644
index 0000000..34361cd
--- /dev/null
+++ b/source3/lib/netapi/examples/netlogon/netlogon_control.c
@@ -0,0 +1,143 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * I_NetLogonControl query
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t function_code = NETLOGON_CONTROL_QUERY;
+ uint32_t level = 1;
+ uint8_t *buffer = NULL;
+ struct NETLOGON_INFO_1 *i1 = NULL;
+ struct NETLOGON_INFO_2 *i2 = NULL;
+ struct NETLOGON_INFO_3 *i3 = NULL;
+ struct NETLOGON_INFO_4 *i4 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("netlogon_control", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ function_code = atoi(poptGetArg(pc));
+ }
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* I_NetLogonControl */
+
+ status = I_NetLogonControl(hostname,
+ function_code,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("I_NetLogonControl failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ if (!buffer) {
+ goto out;
+ }
+
+ switch (level) {
+ case 1:
+ i1 = (struct NETLOGON_INFO_1 *)buffer;
+
+ printf("Flags: %x\n", i1->netlog1_flags);
+ printf("Connection Status Status = %d 0x%x %s\n",
+ i1->netlog1_pdc_connection_status,
+ i1->netlog1_pdc_connection_status,
+ libnetapi_errstr(i1->netlog1_pdc_connection_status));
+
+ break;
+ case 2:
+ i2 = (struct NETLOGON_INFO_2 *)buffer;
+
+ printf("Flags: %x\n", i2->netlog2_flags);
+ printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name);
+ printf("Trusted DC Connection Status Status = %d 0x%x %s\n",
+ i2->netlog2_tc_connection_status,
+ i2->netlog2_tc_connection_status,
+ libnetapi_errstr(i2->netlog2_tc_connection_status));
+ printf("Trust Verification Status Status = %d 0x%x %s\n",
+ i2->netlog2_pdc_connection_status,
+ i2->netlog2_pdc_connection_status,
+ libnetapi_errstr(i2->netlog2_pdc_connection_status));
+
+ break;
+ case 3:
+ i3 = (struct NETLOGON_INFO_3 *)buffer;
+
+ printf("Flags: %x\n", i3->netlog1_flags);
+ printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts);
+
+ break;
+ case 4:
+ i4 = (struct NETLOGON_INFO_4 *)buffer;
+
+ printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name);
+ printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name);
+
+ break;
+ default:
+ break;
+ }
+
+ out:
+ NetApiBufferFree(buffer);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/netlogon/netlogon_control2.c b/source3/lib/netapi/examples/netlogon/netlogon_control2.c
new file mode 100644
index 0000000..72315c9
--- /dev/null
+++ b/source3/lib/netapi/examples/netlogon/netlogon_control2.c
@@ -0,0 +1,147 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * I_NetLogonControl2 query
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t function_code = NETLOGON_CONTROL_QUERY;
+ uint32_t level = 1;
+ uint8_t *buffer = NULL;
+ struct NETLOGON_INFO_1 *i1 = NULL;
+ struct NETLOGON_INFO_2 *i2 = NULL;
+ struct NETLOGON_INFO_3 *i3 = NULL;
+ struct NETLOGON_INFO_4 *i4 = NULL;
+ char *domain = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("netlogon_control", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ function_code = atoi(poptGetArg(pc));
+ }
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ domain = strdup("TEST");
+
+ /* I_NetLogonControl2 */
+
+ status = I_NetLogonControl2(hostname,
+ function_code,
+ level,
+ (uint8_t *)domain,
+ &buffer);
+ if (status != 0) {
+ printf("I_NetLogonControl2 failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ if (!buffer) {
+ goto out;
+ }
+
+ switch (level) {
+ case 1:
+ i1 = (struct NETLOGON_INFO_1 *)buffer;
+
+ printf("Flags: %x\n", i1->netlog1_flags);
+ printf("Connection Status Status = %d 0x%x %s\n",
+ i1->netlog1_pdc_connection_status,
+ i1->netlog1_pdc_connection_status,
+ libnetapi_errstr(i1->netlog1_pdc_connection_status));
+
+ break;
+ case 2:
+ i2 = (struct NETLOGON_INFO_2 *)buffer;
+
+ printf("Flags: %x\n", i2->netlog2_flags);
+ printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name);
+ printf("Trusted DC Connection Status Status = %d 0x%x %s\n",
+ i2->netlog2_tc_connection_status,
+ i2->netlog2_tc_connection_status,
+ libnetapi_errstr(i2->netlog2_tc_connection_status));
+ printf("Trust Verification Status Status = %d 0x%x %s\n",
+ i2->netlog2_pdc_connection_status,
+ i2->netlog2_pdc_connection_status,
+ libnetapi_errstr(i2->netlog2_pdc_connection_status));
+
+ break;
+ case 3:
+ i3 = (struct NETLOGON_INFO_3 *)buffer;
+
+ printf("Flags: %x\n", i3->netlog1_flags);
+ printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts);
+
+ break;
+ case 4:
+ i4 = (struct NETLOGON_INFO_4 *)buffer;
+
+ printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name);
+ printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name);
+
+ break;
+ default:
+ break;
+ }
+
+ out:
+ NetApiBufferFree(buffer);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/netlogon/nltest.c b/source3/lib/netapi/examples/netlogon/nltest.c
new file mode 100644
index 0000000..2dd368f
--- /dev/null
+++ b/source3/lib/netapi/examples/netlogon/nltest.c
@@ -0,0 +1,677 @@
+/*
+ * Samba Unix/Linux SMB client library
+ * Distributed SMB/CIFS Server Management Utility
+ * Nltest netlogon testing tool
+ *
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+enum {
+ OPT_SERVER = 1,
+ OPT_DBFLAG,
+ OPT_SC_QUERY,
+ OPT_SC_RESET,
+ OPT_SC_VERIFY,
+ OPT_SC_CHANGE_PWD,
+ OPT_DSGETDC,
+ OPT_PDC,
+ OPT_DS,
+ OPT_DSP,
+ OPT_GC,
+ OPT_KDC,
+ OPT_TIMESERV,
+ OPT_GTIMESERV,
+ OPT_WS,
+ OPT_NETBIOS,
+ OPT_DNS,
+ OPT_IP,
+ OPT_FORCE,
+ OPT_WRITABLE,
+ OPT_AVOIDSELF,
+ OPT_LDAPONLY,
+ OPT_BACKG,
+ OPT_DS_6,
+ OPT_TRY_NEXT_CLOSEST_SITE,
+ OPT_SITE,
+ OPT_ACCOUNT,
+ OPT_RET_DNS,
+ OPT_RET_NETBIOS,
+ OPT_DSREGDNS
+};
+
+/****************************************************************
+****************************************************************/
+
+static void print_netlogon_info_result(uint32_t level,
+ uint8_t *buffer)
+{
+ struct NETLOGON_INFO_1 *i1 = NULL;
+ struct NETLOGON_INFO_2 *i2 = NULL;
+ struct NETLOGON_INFO_3 *i3 = NULL;
+ struct NETLOGON_INFO_4 *i4 = NULL;
+
+ if (!buffer) {
+ return;
+ }
+
+ switch (level) {
+ case 1:
+ i1 = (struct NETLOGON_INFO_1 *)buffer;
+
+ printf("Flags: %x\n", i1->netlog1_flags);
+ printf("Connection Status Status = %d 0x%x %s\n",
+ i1->netlog1_pdc_connection_status,
+ i1->netlog1_pdc_connection_status,
+ libnetapi_errstr(i1->netlog1_pdc_connection_status));
+
+ break;
+ case 2:
+ i2 = (struct NETLOGON_INFO_2 *)buffer;
+
+ printf("Flags: %x\n", i2->netlog2_flags);
+ printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name);
+ printf("Trusted DC Connection Status Status = %d 0x%x %s\n",
+ i2->netlog2_tc_connection_status,
+ i2->netlog2_tc_connection_status,
+ libnetapi_errstr(i2->netlog2_tc_connection_status));
+ printf("Trust Verification Status Status = %d 0x%x %s\n",
+ i2->netlog2_pdc_connection_status,
+ i2->netlog2_pdc_connection_status,
+ libnetapi_errstr(i2->netlog2_pdc_connection_status));
+
+ break;
+ case 3:
+ i3 = (struct NETLOGON_INFO_3 *)buffer;
+
+ printf("Flags: %x\n", i3->netlog1_flags);
+ printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts);
+
+ break;
+ case 4:
+ i4 = (struct NETLOGON_INFO_4 *)buffer;
+
+ printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name);
+ printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name);
+
+ break;
+ default:
+ break;
+ }
+}
+
+/****************************************************************
+****************************************************************/
+
+static void print_dc_info_flags(uint32_t flags)
+{
+ if (flags & DS_PDC_FLAG)
+ printf("PDC ");
+ if (flags & DS_GC_FLAG)
+ printf("GC ");
+ if (flags & DS_DS_FLAG)
+ printf("DS ");
+ if (flags & DS_LDAP_FLAG)
+ printf("LDAP ");
+ if (flags & DS_KDC_FLAG)
+ printf("KDC ");
+ if (flags & DS_TIMESERV_FLAG)
+ printf("TIMESERV ");
+ if (flags & DS_GOOD_TIMESERV_FLAG)
+ printf("GTIMESERV ");
+ if (flags & DS_WRITABLE_FLAG)
+ printf("WRITABLE ");
+ if (flags & DS_DNS_FOREST_FLAG)
+ printf("DNS_FOREST ");
+ if (flags & DS_CLOSEST_FLAG)
+ printf("CLOSE_SITE ");
+ if (flags & DS_FULL_SECRET_DOMAIN_6_FLAG)
+ printf("FULL_SECRET ");
+ if (flags & DS_WS_FLAG)
+ printf("WS ");
+ if (flags & DS_DS_8_FLAG)
+ printf("DS_8 ");
+ printf("\n");
+}
+
+/****************************************************************
+****************************************************************/
+
+static void print_dc_info(struct DOMAIN_CONTROLLER_INFO *dc_info)
+{
+ if (dc_info->flags) {
+ printf(" DC: %s\n", dc_info->domain_controller_name);
+ printf(" Address: %s\n", dc_info->domain_controller_address);
+/* printf(" Dom Guid: %s\n", X(domain_guid)); */
+ printf(" Dom Name: %s\n", dc_info->domain_name);
+ printf(" Forest Name: %s\n", dc_info->dns_forest_name);
+ printf(" Dc Site Name: %s\n", dc_info->dc_site_name);
+ printf("Our Site Name: %s\n", dc_info->client_site_name);
+ printf(" Flags: ");
+ print_dc_info_flags(dc_info->flags);
+ } else {
+ printf(" DC: %s\n", dc_info->domain_controller_name);
+ printf(" Address: %s\n", dc_info->domain_controller_address);
+ printf(" Dom Name: %s\n", dc_info->domain_name);
+ }
+}
+
+/****************************************************************
+****************************************************************/
+
+int main(int argc, const char **argv)
+{
+ int opt;
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ char *opt_server = NULL;
+ char *opt_domain = NULL;
+ int opt_dbflag = 0;
+ int opt_pdc = 0;
+ int opt_ds = 0;
+ int opt_dsp = 0;
+ int opt_gc = 0;
+ int opt_kdc = 0;
+ int opt_timeserv = 0;
+ int opt_gtimeserv = 0;
+ int opt_ws = 0;
+ int opt_netbios = 0;
+ int opt_dns = 0;
+ int opt_ip = 0;
+ int opt_force = 0;
+ int opt_writable = 0;
+ int opt_avoidself = 0;
+ int opt_ldaponly = 0;
+ int opt_backg = 0;
+ int opt_ds_6 = 0;
+ int opt_try_next_closest_site = 0;
+ char *opt_site = NULL;
+ char *opt_account = NULL;
+ int opt_ret_dns = 0;
+ int opt_ret_netbios = 0;
+ int opt_dsregdns = 0;
+ uint32_t query_level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t flags = 0;
+ struct DOMAIN_CONTROLLER_INFO *dc_info = NULL;
+
+ poptContext pc;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ {
+ .longName = "server",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_server,
+ .val = OPT_SERVER,
+ .descrip = "Servername",
+ .argDescrip = "SERVER",
+ },
+ {
+ .longName = "dbflag",
+ .shortName = 0,
+ .argInfo = POPT_ARG_INT,
+ .arg = &opt_dbflag,
+ .val = OPT_DBFLAG,
+ .descrip = "New Debug Flag",
+ .argDescrip = "HEXFLAGS",
+ },
+ {
+ .longName = "sc_query",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_domain,
+ .val = OPT_SC_QUERY,
+ .descrip = "Query secure channel for domain on server",
+ .argDescrip = "DOMAIN",
+ },
+ {
+ .longName = "sc_reset",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_domain,
+ .val = OPT_SC_RESET,
+ .descrip = "Reset secure channel for domain on server to dcname",
+ .argDescrip = "DOMAIN",
+ },
+ {
+ .longName = "sc_verify",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_domain,
+ .val = OPT_SC_VERIFY,
+ .descrip = "Verify secure channel for domain on server",
+ .argDescrip = "DOMAIN",
+ },
+ {
+ .longName = "sc_change_pwd",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_domain,
+ .val = OPT_SC_CHANGE_PWD,
+ .descrip = "Change a secure channel password for domain on server",
+ .argDescrip = "DOMAIN",
+ },
+ {
+ .longName = "dsgetdc",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_domain,
+ .val = OPT_DSGETDC,
+ .descrip = "Call DsGetDcName",
+ .argDescrip = "DOMAIN",
+ },
+ {
+ .longName = "pdc",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_pdc,
+ .val = OPT_PDC,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ds",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ds,
+ .val = OPT_DS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "dsp",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_dsp,
+ .val = OPT_DSP,
+ .descrip = NULL,
+ },
+ {
+ .longName = "gc",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_gc,
+ .val = OPT_GC,
+ .descrip = NULL,
+ },
+ {
+ .longName = "kdc",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_kdc,
+ .val = OPT_KDC,
+ .descrip = NULL,
+ },
+ {
+ .longName = "timeserv",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_timeserv,
+ .val = OPT_TIMESERV,
+ .descrip = NULL,
+ },
+ {
+ .longName = "gtimeserv",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_gtimeserv,
+ .val = OPT_GTIMESERV,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ws",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ws,
+ .val = OPT_WS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "netbios",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_netbios,
+ .val = OPT_NETBIOS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "dns",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_dns,
+ .val = OPT_DNS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ip",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ip,
+ .val = OPT_IP,
+ .descrip = NULL,
+ },
+ {
+ .longName = "force",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_force,
+ .val = OPT_FORCE,
+ .descrip = NULL,
+ },
+ {
+ .longName = "writable",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_writable,
+ .val = OPT_WRITABLE,
+ .descrip = NULL,
+ },
+ {
+ .longName = "avoidself",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_avoidself,
+ .val = OPT_AVOIDSELF,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ldaponly",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ldaponly,
+ .val = OPT_LDAPONLY,
+ .descrip = NULL,
+ },
+ {
+ .longName = "backg",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_backg,
+ .val = OPT_BACKG,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ds_6",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ds_6,
+ .val = OPT_DS_6,
+ .descrip = NULL,
+ },
+ {
+ .longName = "try_next_closest_site",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_try_next_closest_site,
+ .val = OPT_TRY_NEXT_CLOSEST_SITE,
+ .descrip = NULL,
+ },
+ {
+ .longName = "site",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_site,
+ .val = OPT_SITE,
+ .descrip = "SITE",
+ },
+ {
+ .longName = "account",
+ .shortName = 0,
+ .argInfo = POPT_ARG_STRING,
+ .arg = &opt_account,
+ .val = OPT_ACCOUNT,
+ .descrip = "ACCOUNT",
+ },
+ {
+ .longName = "ret_dns",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ret_dns,
+ .val = OPT_RET_DNS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "ret_netbios",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_ret_netbios,
+ .val = OPT_RET_NETBIOS,
+ .descrip = NULL,
+ },
+ {
+ .longName = "dsregdns",
+ .shortName = 0,
+ .argInfo = POPT_ARG_NONE,
+ .arg = &opt_dsregdns,
+ .val = OPT_DSREGDNS,
+ .descrip = "Force registration of all DC-specific DNS records",
+ },
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("nltest", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "<options>");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (argc == 1) {
+ poptPrintHelp(pc, stderr, 0);
+ goto done;
+ }
+
+ poptResetContext(pc);
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+
+ case OPT_SERVER:
+
+ if ((opt_server[0] == '/' && opt_server[1] == '/') ||
+ (opt_server[0] == '\\' && opt_server[1] == '\\')) {
+ opt_server += 2;
+ }
+
+ break;
+
+ case OPT_DBFLAG:
+ query_level = 1;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_SET_DBFLAG,
+ query_level,
+ (uint8_t *)&opt_dbflag,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_SC_QUERY:
+ query_level = 2;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_TC_QUERY,
+ query_level,
+ (uint8_t *)opt_domain,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_SC_VERIFY:
+ query_level = 2;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_TC_VERIFY,
+ query_level,
+ (uint8_t *)opt_domain,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_SC_RESET:
+ query_level = 2;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_REDISCOVER,
+ query_level,
+ (uint8_t *)opt_domain,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_SC_CHANGE_PWD:
+ query_level = 1;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_CHANGE_PASSWORD,
+ query_level,
+ (uint8_t *)opt_domain,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_DSREGDNS:
+ query_level = 1;
+ status = I_NetLogonControl2(opt_server,
+ NETLOGON_CONTROL_FORCE_DNS_REG,
+ query_level,
+ NULL,
+ &buffer);
+ if (status != 0) {
+ fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_netlogon_info_result(query_level, buffer);
+
+ break;
+ case OPT_DSGETDC:
+ if (opt_pdc)
+ flags |= DS_PDC_REQUIRED;
+ if (opt_ds)
+ flags |= DS_DIRECTORY_SERVICE_REQUIRED;
+ if (opt_dsp)
+ flags |= DS_DIRECTORY_SERVICE_PREFERRED;
+ if (opt_kdc)
+ flags |= DS_KDC_REQUIRED;
+ if (opt_timeserv)
+ flags |= DS_TIMESERV_REQUIRED;
+ if (opt_gtimeserv)
+ flags |= DS_GOOD_TIMESERV_PREFERRED;
+ if (opt_ws)
+ flags |= DS_WEB_SERVICE_REQUIRED;
+ if (opt_netbios)
+ flags |= DS_IS_FLAT_NAME;
+ if (opt_dns)
+ flags |= DS_IS_DNS_NAME;
+ if (opt_ip)
+ flags |= DS_IP_REQUIRED;
+ if (opt_force)
+ flags |= DS_FORCE_REDISCOVERY;
+ if (opt_writable)
+ flags |= DS_WRITABLE_REQUIRED;
+ if (opt_avoidself)
+ flags |= DS_AVOID_SELF;
+ if (opt_ldaponly)
+ flags |= DS_ONLY_LDAP_NEEDED;
+ if (opt_backg)
+ flags |= DS_BACKGROUND_ONLY;
+ if (opt_ds_6)
+ flags |= DS_DIRECTORY_SERVICE_6_REQUIRED;
+ if (opt_try_next_closest_site)
+ flags |= DS_TRY_NEXTCLOSEST_SITE;
+ if (opt_ret_dns)
+ flags |= DS_RETURN_DNS_NAME;
+ if (opt_ret_netbios)
+ flags |= DS_RETURN_FLAT_NAME;
+
+ status = DsGetDcName(opt_server,
+ opt_domain,
+ NULL, /* domain_guid */
+ opt_site,
+ flags,
+ &dc_info);
+ if (status != 0) {
+ fprintf(stderr, "DsGetDcName failed: Status = %d 0x%x %s\n",
+ status, status,
+ libnetapi_get_error_string(ctx, status));
+ goto done;
+ }
+
+ print_dc_info(dc_info);
+
+ break;
+ default:
+ continue;
+ }
+ }
+
+ printf("The command completed successfully\n");
+ status = 0;
+
+ done:
+
+ printf("\n");
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/server/remote_tod.c b/source3/lib/netapi/examples/server/remote_tod.c
new file mode 100644
index 0000000..7636f6a
--- /dev/null
+++ b/source3/lib/netapi/examples/server/remote_tod.c
@@ -0,0 +1,83 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetRemoteTOD query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ struct TIME_OF_DAY_INFO *tod = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("tod", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+
+ /* NetRemoteTOD */
+
+ status = NetRemoteTOD(hostname,
+ (uint8_t **)&tod);
+ if (status != 0) {
+ printf("NetRemoteTOD failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ } else {
+ printf("%d-%d-%d %d:%d:%d\n",
+ tod->tod_day, tod->tod_month, tod->tod_year,
+ tod->tod_hours, tod->tod_mins, tod->tod_secs);
+ NetApiBufferFree(tod);
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/server/server_getinfo.c b/source3/lib/netapi/examples/server/server_getinfo.c
new file mode 100644
index 0000000..7836faa
--- /dev/null
+++ b/source3/lib/netapi/examples/server/server_getinfo.c
@@ -0,0 +1,136 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetServerGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 100;
+
+ struct SERVER_INFO_100 *i100;
+ struct SERVER_INFO_101 *i101;
+ struct SERVER_INFO_102 *i102;
+ struct SERVER_INFO_1005 *i1005;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("server_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetServerGetInfo */
+
+ status = NetServerGetInfo(hostname,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetServerGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 100:
+ i100 = (struct SERVER_INFO_100 *)buffer;
+ printf("platform id: %d\n", i100->sv100_platform_id);
+ printf("name: %s\n", i100->sv100_name);
+ break;
+ case 101:
+ i101 = (struct SERVER_INFO_101 *)buffer;
+ printf("platform id: %d\n", i101->sv101_platform_id);
+ printf("name: %s\n", i101->sv101_name);
+ printf("version major: %d\n", i101->sv101_version_major);
+ printf("version minor: %d\n", i101->sv101_version_minor);
+ printf("type: 0x%08x\n", i101->sv101_type);
+ printf("comment: %s\n", i101->sv101_comment);
+ break;
+ case 102:
+ i102 = (struct SERVER_INFO_102 *)buffer;
+ printf("platform id: %d\n", i102->sv102_platform_id);
+ printf("name: %s\n", i102->sv102_name);
+ printf("version major: %d\n", i102->sv102_version_major);
+ printf("version minor: %d\n", i102->sv102_version_minor);
+ printf("type: 0x%08x\n", i102->sv102_type);
+ printf("comment: %s\n", i102->sv102_comment);
+ printf("users: %d\n", i102->sv102_users);
+ printf("disc: %d\n", i102->sv102_disc);
+ printf("hidden: %d\n", i102->sv102_hidden);
+ printf("announce: %d\n", i102->sv102_announce);
+ printf("anndelta: %d\n", i102->sv102_anndelta);
+ printf("licenses: %d\n", i102->sv102_licenses);
+ printf("userpath: %s\n", i102->sv102_userpath);
+ break;
+ case 402:
+ break;
+ case 403:
+ break;
+ case 502:
+ break;
+ case 503:
+ break;
+ case 1005:
+ i1005 = (struct SERVER_INFO_1005 *)buffer;
+ printf("comment: %s\n", i1005->sv1005_comment);
+ break;
+ default:
+ break;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/share/share_add.c b/source3/lib/netapi/examples/share/share_add.c
new file mode 100644
index 0000000..760381a
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_add.c
@@ -0,0 +1,105 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareAdd query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *sharename = NULL;
+ const char *path = NULL;
+ uint32_t parm_err = 0;
+
+ struct SHARE_INFO_2 i2;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_add", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname sharename path");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ sharename = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ path = poptGetArg(pc);
+
+ /* NetShareAdd */
+
+ i2.shi2_netname = sharename;
+ i2.shi2_type = 0;
+ i2.shi2_remark = "Test share created via NetApi";
+ i2.shi2_permissions = 0;
+ i2.shi2_max_uses = (uint32_t)-1;
+ i2.shi2_current_uses = 0;
+ i2.shi2_path = path;
+ i2.shi2_passwd = NULL;
+
+ status = NetShareAdd(hostname,
+ 2,
+ (uint8_t *)&i2,
+ &parm_err);
+ if (status != 0) {
+ printf("NetShareAdd failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/share/share_del.c b/source3/lib/netapi/examples/share/share_del.c
new file mode 100644
index 0000000..20e3ce5
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_del.c
@@ -0,0 +1,85 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareDel query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *sharename = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_del", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname sharename");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ sharename = poptGetArg(pc);
+
+ /* NetShareDel */
+
+ status = NetShareDel(hostname,
+ sharename,
+ 0);
+ if (status != 0) {
+ printf("NetShareDel failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/share/share_enum.c b/source3/lib/netapi/examples/share/share_enum.c
new file mode 100644
index 0000000..b1f4043
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_enum.c
@@ -0,0 +1,142 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareEnum query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int i;
+
+ struct SHARE_INFO_0 *i0 = NULL;
+ struct SHARE_INFO_1 *i1 = NULL;
+ struct SHARE_INFO_2 *i2 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_enum", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetShareEnum */
+
+ do {
+ status = NetShareEnum(hostname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ printf("total entries: %d\n", total_entries);
+ switch (level) {
+ case 0:
+ i0 = (struct SHARE_INFO_0 *)buffer;
+ break;
+ case 1:
+ i1 = (struct SHARE_INFO_1 *)buffer;
+ break;
+ case 2:
+ i2 = (struct SHARE_INFO_2 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d netname: %s\n", i, i0->shi0_netname);
+ i0++;
+ break;
+ case 1:
+ printf("#%d netname: %s\n", i, i1->shi1_netname);
+ printf("#%d type: %d\n", i, i1->shi1_type);
+ printf("#%d remark: %s\n", i, i1->shi1_remark);
+ i1++;
+ break;
+ case 2:
+ printf("#%d netname: %s\n", i, i2->shi2_netname);
+ printf("#%d type: %d\n", i, i2->shi2_type);
+ printf("#%d remark: %s\n", i, i2->shi2_remark);
+ printf("#%d permissions: %d\n", i, i2->shi2_permissions);
+ printf("#%d max users: %d\n", i, i2->shi2_max_uses);
+ printf("#%d current users: %d\n", i, i2->shi2_current_uses);
+ printf("#%d path: %s\n", i, i2->shi2_path);
+ printf("#%d password: %s\n", i, i2->shi2_passwd);
+ i2++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetShareEnum failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/share/share_getinfo.c b/source3/lib/netapi/examples/share/share_getinfo.c
new file mode 100644
index 0000000..479da5c
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_getinfo.c
@@ -0,0 +1,152 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *sharename = NULL;
+ uint32_t level = 2;
+ uint8_t *buffer = NULL;
+
+ struct SHARE_INFO_0 *i0 = NULL;
+ struct SHARE_INFO_1 *i1 = NULL;
+ struct SHARE_INFO_2 *i2 = NULL;
+ struct SHARE_INFO_501 *i501 = NULL;
+ struct SHARE_INFO_1005 *i1005 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname sharename level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ sharename = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetShareGetInfo */
+
+ status = NetShareGetInfo(hostname,
+ sharename,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetShareGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 0:
+ i0 = (struct SHARE_INFO_0 *)buffer;
+ break;
+ case 1:
+ i1 = (struct SHARE_INFO_1 *)buffer;
+ break;
+ case 2:
+ i2 = (struct SHARE_INFO_2 *)buffer;
+ break;
+ case 501:
+ i501 = (struct SHARE_INFO_501 *)buffer;
+ break;
+ case 1005:
+ i1005 = (struct SHARE_INFO_1005 *)buffer;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (level) {
+ case 0:
+ printf("netname: %s\n", i0->shi0_netname);
+ break;
+ case 1:
+ printf("netname: %s\n", i1->shi1_netname);
+ printf("type: %d\n", i1->shi1_type);
+ printf("remark: %s\n", i1->shi1_remark);
+ break;
+ case 2:
+ printf("netname: %s\n", i2->shi2_netname);
+ printf("type: %d\n", i2->shi2_type);
+ printf("remark: %s\n", i2->shi2_remark);
+ printf("permissions: %d\n", i2->shi2_permissions);
+ printf("max users: %d\n", i2->shi2_max_uses);
+ printf("current users: %d\n", i2->shi2_current_uses);
+ printf("path: %s\n", i2->shi2_path);
+ printf("password: %s\n", i2->shi2_passwd);
+ break;
+ case 501:
+ printf("netname: %s\n", i501->shi501_netname);
+ printf("type: %d\n", i501->shi501_type);
+ printf("remark: %s\n", i501->shi501_remark);
+ printf("flags: %d\n", i501->shi501_flags);
+ break;
+ case 1005:
+ printf("flags: %d\n", i1005->shi1005_flags);
+ break;
+ default:
+ break;
+ }
+ NetApiBufferFree(buffer);
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/share/share_setinfo.c b/source3/lib/netapi/examples/share/share_setinfo.c
new file mode 100644
index 0000000..f4748f4
--- /dev/null
+++ b/source3/lib/netapi/examples/share/share_setinfo.c
@@ -0,0 +1,105 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShareSetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *sharename = NULL;
+ const char *comment = "NetApi generated Share comment";
+ uint32_t level = 1004;
+ uint8_t *buffer = NULL;
+ uint32_t parm_err = 0;
+
+ struct SHARE_INFO_1004 i1004;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("share_setinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname sharename comment");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ sharename = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ comment = poptGetArg(pc);
+ }
+
+ /* NetShareSetInfo */
+ switch (level) {
+ case 1004:
+ i1004.shi1004_remark = comment;
+ buffer = (uint8_t *)&i1004;
+ break;
+ default:
+ break;
+ }
+
+ status = NetShareSetInfo(hostname,
+ sharename,
+ level,
+ buffer,
+ &parm_err);
+ if (status != 0) {
+ printf("NetShareSetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/shutdown/shutdown_abort.c b/source3/lib/netapi/examples/shutdown/shutdown_abort.c
new file mode 100644
index 0000000..8f24a7a
--- /dev/null
+++ b/source3/lib/netapi/examples/shutdown/shutdown_abort.c
@@ -0,0 +1,76 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShutdownAbort query
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("shutdown_abort", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ /* NetShutdownAbort */
+
+ status = NetShutdownAbort(hostname);
+ if (status != 0) {
+ printf("NetShutdownAbort failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/shutdown/shutdown_init.c b/source3/lib/netapi/examples/shutdown/shutdown_init.c
new file mode 100644
index 0000000..73d23bb
--- /dev/null
+++ b/source3/lib/netapi/examples/shutdown/shutdown_init.c
@@ -0,0 +1,94 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetShutdownInit query
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *message = NULL;
+ uint32_t timeout = 30;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("shutdown_init", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname message timeout");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ message = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ timeout = atoi(poptGetArg(pc));
+
+ /* NetShutdownInit */
+
+ status = NetShutdownInit(hostname,
+ message,
+ timeout,
+ 1, /* close apps */
+ 1); /* reboot */
+ if (status != 0) {
+ printf("NetShutdownInit failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_add.c b/source3/lib/netapi/examples/user/user_add.c
new file mode 100644
index 0000000..5452f77
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_add.c
@@ -0,0 +1,103 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserAdd query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ const char *password = NULL;
+ struct USER_INFO_1 info1;
+ uint32_t parm_error = 0;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_add", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username password");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ password = poptGetArg(pc);
+
+ /* NetUserAdd */
+
+ info1.usri1_name = username;
+ info1.usri1_password = password;
+ info1.usri1_password_age = 0;
+ info1.usri1_priv = 0;
+ info1.usri1_home_dir = NULL;
+ info1.usri1_comment = "User created using Samba NetApi Example code";
+ info1.usri1_flags = 0;
+ info1.usri1_script_path = NULL;
+
+ status = NetUserAdd(hostname,
+ 1,
+ (uint8_t *)&info1,
+ &parm_error);
+ if (status != 0) {
+ printf("NetUserAdd failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_chgpwd.c b/source3/lib/netapi/examples/user/user_chgpwd.c
new file mode 100644
index 0000000..8b37ec2
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_chgpwd.c
@@ -0,0 +1,99 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserChangePassword query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ const char *old_password = NULL;
+ const char *new_password = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_chgpwd", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username old_password new_password");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ old_password = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ new_password = poptGetArg(pc);
+
+ /* NetUserChangePassword */
+
+ status = NetUserChangePassword(hostname,
+ username,
+ old_password,
+ new_password);
+ if (status != 0) {
+ printf("NetUserChangePassword failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_del.c b/source3/lib/netapi/examples/user/user_del.c
new file mode 100644
index 0000000..9cf28a9
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_del.c
@@ -0,0 +1,82 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserDel query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_del", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ /* NetUserDel */
+
+ status = NetUserDel(hostname, username);
+ if (status != 0) {
+ printf("NetUserDel failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_dispinfo.c b/source3/lib/netapi/examples/user/user_dispinfo.c
new file mode 100644
index 0000000..23024fe
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_dispinfo.c
@@ -0,0 +1,100 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetQueryDisplayInformation query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ void *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t idx = 0;
+ int i;
+
+ struct NET_DISPLAY_USER *user;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_dispinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ /* NetQueryDisplayInformation */
+
+ do {
+ status = NetQueryDisplayInformation(hostname,
+ 1,
+ idx,
+ 1000,
+ (uint32_t)-1,
+ &entries_read,
+ &buffer);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ user = (struct NET_DISPLAY_USER *)buffer;
+ for (i=0; i<entries_read; i++) {
+ printf("user %d: %s\n", i + idx,
+ user->usri1_name);
+ user++;
+ }
+ NetApiBufferFree(buffer);
+ }
+ idx += entries_read;
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetQueryDisplayInformation failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_enum.c b/source3/lib/netapi/examples/user/user_enum.c
new file mode 100644
index 0000000..cf77bf2
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_enum.c
@@ -0,0 +1,157 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserEnum query
+ * Copyright (C) Guenther Deschner 2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ char *sid_str = NULL;
+ int i;
+
+ struct USER_INFO_0 *info0 = NULL;
+ struct USER_INFO_10 *info10 = NULL;
+ struct USER_INFO_20 *info20 = NULL;
+ struct USER_INFO_23 *info23 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_enum", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetUserEnum */
+
+ do {
+ status = NetUserEnum(hostname,
+ level,
+ FILTER_NORMAL_ACCOUNT,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+
+ switch (level) {
+ case 0:
+ info0 = (struct USER_INFO_0 *)buffer;
+ break;
+ case 10:
+ info10 = (struct USER_INFO_10 *)buffer;
+ break;
+ case 20:
+ info20 = (struct USER_INFO_20 *)buffer;
+ break;
+ case 23:
+ info23 = (struct USER_INFO_23 *)buffer;
+ break;
+ default:
+ break;
+ }
+
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d user: %s\n", i, info0->usri0_name);
+ info0++;
+ break;
+ case 10:
+ printf("#%d user: %s\n", i, info10->usri10_name);
+ printf("#%d comment: %s\n", i, info10->usri10_comment);
+ printf("#%d usr_comment: %s\n", i, info10->usri10_usr_comment);
+ printf("#%d full_name: %s\n", i, info10->usri10_full_name);
+ info10++;
+ break;
+ case 20:
+ printf("#%d user: %s\n", i, info20->usri20_name);
+ printf("#%d comment: %s\n", i, info20->usri20_comment);
+ printf("#%d flags: 0x%08x\n", i, info20->usri20_flags);
+ printf("#%d rid: %d\n", i, info20->usri20_user_id);
+ info20++;
+ break;
+ case 23:
+ printf("#%d user: %s\n", i, info23->usri23_name);
+ printf("#%d comment: %s\n", i, info23->usri23_comment);
+ printf("#%d flags: 0x%08x\n", i, info23->usri23_flags);
+ if (ConvertSidToStringSid(info23->usri23_user_sid,
+ &sid_str)) {
+ printf("#%d sid: %s\n", i, sid_str);
+ free(sid_str);
+ }
+ info23++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetUserEnum failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_getgroups.c b/source3/lib/netapi/examples/user/user_getgroups.c
new file mode 100644
index 0000000..939415e
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_getgroups.c
@@ -0,0 +1,133 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserGetGroups query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ int i;
+
+ struct GROUP_USERS_INFO_0 *info0 = NULL;
+ struct GROUP_USERS_INFO_1 *info1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_getgroups", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetUserGetGroups */
+
+ do {
+ status = NetUserGetGroups(hostname,
+ username,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_USERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_USERS_INFO_1 *)buffer;
+ break;
+ default:
+ break;
+ }
+
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d group: %s\n", i, info0->grui0_name);
+ info0++;
+ break;
+ case 1:
+ printf("#%d group: %s\n", i, info1->grui1_name);
+ printf("#%d attributes: %d\n", i, info1->grui1_attributes);
+ info1++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetUserGetGroups failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_getinfo.c b/source3/lib/netapi/examples/user/user_getinfo.c
new file mode 100644
index 0000000..9e95260
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_getinfo.c
@@ -0,0 +1,293 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserGetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ char *sid_str = NULL;
+ int i;
+
+ struct USER_INFO_0 *u0;
+ struct USER_INFO_1 *u1;
+ struct USER_INFO_2 *u2;
+ struct USER_INFO_3 *u3;
+ struct USER_INFO_4 *u4;
+ struct USER_INFO_10 *u10;
+ struct USER_INFO_11 *u11;
+ struct USER_INFO_20 *u20;
+ struct USER_INFO_23 *u23;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_getinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetUserGetInfo */
+
+ status = NetUserGetInfo(hostname,
+ username,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetUserGetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 0:
+ u0 = (struct USER_INFO_0 *)buffer;
+ printf("name: %s\n", u0->usri0_name);
+ break;
+ case 1:
+ u1 = (struct USER_INFO_1 *)buffer;
+ printf("name: %s\n", u1->usri1_name);
+ printf("password: %s\n", u1->usri1_password);
+ printf("password_age: %d\n", u1->usri1_password_age);
+ printf("priv: %d\n", u1->usri1_priv);
+ printf("homedir: %s\n", u1->usri1_home_dir);
+ printf("comment: %s\n", u1->usri1_comment);
+ printf("flags: 0x%08x\n", u1->usri1_flags);
+ printf("script: %s\n", u1->usri1_script_path);
+ break;
+ case 2:
+ u2 = (struct USER_INFO_2 *)buffer;
+ printf("name: %s\n", u2->usri2_name);
+ printf("password: %s\n", u2->usri2_password);
+ printf("password_age: %d\n", u2->usri2_password_age);
+ printf("priv: %d\n", u2->usri2_priv);
+ printf("homedir: %s\n", u2->usri2_home_dir);
+ printf("comment: %s\n", u2->usri2_comment);
+ printf("flags: 0x%08x\n", u2->usri2_flags);
+ printf("script: %s\n", u2->usri2_script_path);
+ printf("auth flags: 0x%08x\n", u2->usri2_auth_flags);
+ printf("full name: %s\n", u2->usri2_full_name);
+ printf("user comment: %s\n", u2->usri2_usr_comment);
+ printf("user parameters: %s\n", u2->usri2_parms);
+ printf("workstations: %s\n", u2->usri2_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u2->usri2_acct_expires);
+ printf("max storage: %d\n", u2->usri2_max_storage);
+ printf("units per week: %d\n", u2->usri2_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u2->usri2_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u2->usri2_bad_pw_count);
+ printf("logon count: %d\n", u2->usri2_num_logons);
+ printf("logon server: %s\n", u2->usri2_logon_server);
+ printf("country code: %d\n", u2->usri2_country_code);
+ printf("code page: %d\n", u2->usri2_code_page);
+ break;
+ case 3:
+ u3 = (struct USER_INFO_3 *)buffer;
+ printf("name: %s\n", u3->usri3_name);
+ printf("password_age: %d\n", u3->usri3_password_age);
+ printf("priv: %d\n", u3->usri3_priv);
+ printf("homedir: %s\n", u3->usri3_home_dir);
+ printf("comment: %s\n", u3->usri3_comment);
+ printf("flags: 0x%08x\n", u3->usri3_flags);
+ printf("script: %s\n", u3->usri3_script_path);
+ printf("auth flags: 0x%08x\n", u3->usri3_auth_flags);
+ printf("full name: %s\n", u3->usri3_full_name);
+ printf("user comment: %s\n", u3->usri3_usr_comment);
+ printf("user parameters: %s\n", u3->usri3_parms);
+ printf("workstations: %s\n", u3->usri3_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u3->usri3_acct_expires);
+ printf("max storage: %d\n", u3->usri3_max_storage);
+ printf("units per week: %d\n", u3->usri3_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u3->usri3_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u3->usri3_bad_pw_count);
+ printf("logon count: %d\n", u3->usri3_num_logons);
+ printf("logon server: %s\n", u3->usri3_logon_server);
+ printf("country code: %d\n", u3->usri3_country_code);
+ printf("code page: %d\n", u3->usri3_code_page);
+ printf("user id: %d\n", u3->usri3_user_id);
+ printf("primary group id: %d\n", u3->usri3_primary_group_id);
+ printf("profile: %s\n", u3->usri3_profile);
+ printf("home dir drive: %s\n", u3->usri3_home_dir_drive);
+ printf("password expired: %d\n", u3->usri3_password_expired);
+ break;
+ case 4:
+ u4 = (struct USER_INFO_4 *)buffer;
+ printf("name: %s\n", u4->usri4_name);
+ printf("password: %s\n", u4->usri4_password);
+ printf("password_age: %d\n", u4->usri4_password_age);
+ printf("priv: %d\n", u4->usri4_priv);
+ printf("homedir: %s\n", u4->usri4_home_dir);
+ printf("comment: %s\n", u4->usri4_comment);
+ printf("flags: 0x%08x\n", u4->usri4_flags);
+ printf("script: %s\n", u4->usri4_script_path);
+ printf("auth flags: 0x%08x\n", u4->usri4_auth_flags);
+ printf("full name: %s\n", u4->usri4_full_name);
+ printf("user comment: %s\n", u4->usri4_usr_comment);
+ printf("user parameters: %s\n", u4->usri4_parms);
+ printf("workstations: %s\n", u4->usri4_workstations);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_last_logoff);
+ printf("account expires (seconds since jan. 1, 1970 GMT): %d\n",
+ u4->usri4_acct_expires);
+ printf("max storage: %d\n", u4->usri4_max_storage);
+ printf("units per week: %d\n", u4->usri4_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u4->usri4_logon_hours[i]);
+ }
+ printf("\n");
+ printf("bad password count: %d\n", u4->usri4_bad_pw_count);
+ printf("logon count: %d\n", u4->usri4_num_logons);
+ printf("logon server: %s\n", u4->usri4_logon_server);
+ printf("country code: %d\n", u4->usri4_country_code);
+ printf("code page: %d\n", u4->usri4_code_page);
+ if (ConvertSidToStringSid(u4->usri4_user_sid,
+ &sid_str)) {
+ printf("user_sid: %s\n", sid_str);
+ free(sid_str);
+ }
+ printf("primary group id: %d\n", u4->usri4_primary_group_id);
+ printf("profile: %s\n", u4->usri4_profile);
+ printf("home dir drive: %s\n", u4->usri4_home_dir_drive);
+ printf("password expired: %d\n", u4->usri4_password_expired);
+ break;
+ case 10:
+ u10 = (struct USER_INFO_10 *)buffer;
+ printf("name: %s\n", u10->usri10_name);
+ printf("comment: %s\n", u10->usri10_comment);
+ printf("usr_comment: %s\n", u10->usri10_usr_comment);
+ printf("full_name: %s\n", u10->usri10_full_name);
+ break;
+ case 11:
+ u11 = (struct USER_INFO_11 *)buffer;
+ printf("name: %s\n", u11->usri11_name);
+ printf("comment: %s\n", u11->usri11_comment);
+ printf("user comment: %s\n", u11->usri11_usr_comment);
+ printf("full name: %s\n", u11->usri11_full_name);
+ printf("priv: %d\n", u11->usri11_priv);
+ printf("auth flags: 0x%08x\n", u11->usri11_auth_flags);
+ printf("password_age: %d\n", u11->usri11_password_age);
+ printf("homedir: %s\n", u11->usri11_home_dir);
+ printf("user parameters: %s\n", u11->usri11_parms);
+ printf("last logon (seconds since jan. 1, 1970 GMT): %d\n",
+ u11->usri11_last_logon);
+ printf("last logoff (seconds since jan. 1, 1970 GMT): %d\n",
+ u11->usri11_last_logoff);
+ printf("bad password count: %d\n", u11->usri11_bad_pw_count);
+ printf("logon count: %d\n", u11->usri11_num_logons);
+ printf("logon server: %s\n", u11->usri11_logon_server);
+ printf("country code: %d\n", u11->usri11_country_code);
+ printf("workstations: %s\n", u11->usri11_workstations);
+ printf("max storage: %d\n", u11->usri11_max_storage);
+ printf("units per week: %d\n", u11->usri11_units_per_week);
+ printf("logon hours:");
+ for (i=0; i<21; i++) {
+ printf(" %x", (uint8_t)u11->usri11_logon_hours[i]);
+ }
+ printf("\n");
+ printf("code page: %d\n", u11->usri11_code_page);
+ break;
+ case 20:
+ u20 = (struct USER_INFO_20 *)buffer;
+ printf("name: %s\n", u20->usri20_name);
+ printf("comment: %s\n", u20->usri20_comment);
+ printf("flags: 0x%08x\n", u20->usri20_flags);
+ printf("rid: %d\n", u20->usri20_user_id);
+ break;
+ case 23:
+ u23 = (struct USER_INFO_23 *)buffer;
+ printf("name: %s\n", u23->usri23_name);
+ printf("comment: %s\n", u23->usri23_comment);
+ printf("flags: 0x%08x\n", u23->usri23_flags);
+ if (ConvertSidToStringSid(u23->usri23_user_sid,
+ &sid_str)) {
+ printf("user_sid: %s\n", sid_str);
+ free(sid_str);
+ }
+ break;
+ default:
+ break;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_getlocalgroups.c b/source3/lib/netapi/examples/user/user_getlocalgroups.c
new file mode 100644
index 0000000..133104d
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_getlocalgroups.c
@@ -0,0 +1,122 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserGetLocalGroups query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t flags = 0;
+ int i;
+
+ struct LOCALGROUP_USERS_INFO_0 *info0 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_getlocalgroups", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ /* NetUserGetLocalGroups */
+
+ do {
+ status = NetUserGetLocalGroups(hostname,
+ username,
+ level,
+ flags,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+
+ switch (level) {
+ case 0:
+ info0 = (struct LOCALGROUP_USERS_INFO_0 *)buffer;
+ break;
+ default:
+ break;
+ }
+
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ printf("#%d group: %s\n", i, info0->lgrui0_name);
+ info0++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status != 0) {
+ printf("NetUserGetLocalGroups failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_modalsget.c b/source3/lib/netapi/examples/user/user_modalsget.c
new file mode 100644
index 0000000..4dcb41b
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_modalsget.c
@@ -0,0 +1,131 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserModalsGet query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ char *sid_str = NULL;
+
+ struct USER_MODALS_INFO_0 *u0;
+ struct USER_MODALS_INFO_1 *u1;
+ struct USER_MODALS_INFO_2 *u2;
+ struct USER_MODALS_INFO_3 *u3;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_modalsget", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ /* NetUserModalsGet */
+
+ status = NetUserModalsGet(hostname,
+ level,
+ &buffer);
+ if (status != 0) {
+ printf("NetUserModalsGet failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ switch (level) {
+ case 0:
+ u0 = (struct USER_MODALS_INFO_0 *)buffer;
+ printf("min passwd len: %d character\n",
+ u0->usrmod0_min_passwd_len);
+ printf("max passwd age: %d (days)\n",
+ u0->usrmod0_max_passwd_age/86400);
+ printf("min passwd age: %d (days)\n",
+ u0->usrmod0_min_passwd_age/86400);
+ printf("force logoff: %d (seconds)\n",
+ u0->usrmod0_force_logoff);
+ printf("password history length: %d entries\n",
+ u0->usrmod0_password_hist_len);
+ break;
+ case 1:
+ u1 = (struct USER_MODALS_INFO_1 *)buffer;
+ printf("role: %d\n", u1->usrmod1_role);
+ printf("primary: %s\n", u1->usrmod1_primary);
+ break;
+ case 2:
+ u2 = (struct USER_MODALS_INFO_2 *)buffer;
+ printf("domain name: %s\n", u2->usrmod2_domain_name);
+ if (ConvertSidToStringSid(u2->usrmod2_domain_id,
+ &sid_str)) {
+ printf("domain sid: %s\n", sid_str);
+ free(sid_str);
+ }
+ break;
+ case 3:
+ u3 = (struct USER_MODALS_INFO_3 *)buffer;
+ printf("lockout duration: %d (seconds)\n",
+ u3->usrmod3_lockout_duration);
+ printf("lockout observation window: %d (seconds)\n",
+ u3->usrmod3_lockout_observation_window);
+ printf("lockout threshold: %d entries\n",
+ u3->usrmod3_lockout_threshold);
+ break;
+ default:
+ break;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_modalsset.c b/source3/lib/netapi/examples/user/user_modalsset.c
new file mode 100644
index 0000000..a5cdc44
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_modalsset.c
@@ -0,0 +1,132 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserModalsSet query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t level = 0;
+ uint32_t parm_err = 0;
+
+ struct USER_MODALS_INFO_0 u0;
+ struct USER_MODALS_INFO_1001 u1001;
+ struct USER_MODALS_INFO_1002 u1002;
+ struct USER_MODALS_INFO_1003 u1003;
+ struct USER_MODALS_INFO_1004 u1004;
+ struct USER_MODALS_INFO_1005 u1005;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_modalsset", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname level value");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (poptPeekArg(pc)) {
+ level = atoi(poptGetArg(pc));
+ }
+
+ switch (level) {
+ case 0:
+ u0.usrmod0_min_passwd_len = 0;
+ u0.usrmod0_max_passwd_age = (86400 * 30); /* once a month */
+ u0.usrmod0_min_passwd_age = 0;
+ u0.usrmod0_force_logoff = TIMEQ_FOREVER;
+ u0.usrmod0_password_hist_len = 0;
+ buffer = (uint8_t *)&u0;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ break;
+ case 1001:
+ u1001.usrmod1001_min_passwd_len = 0;
+ buffer = (uint8_t *)&u1001;
+ break;
+ case 1002:
+ u1002.usrmod1002_max_passwd_age = 0;
+ buffer = (uint8_t *)&u1002;
+ break;
+ case 1003:
+ u1003.usrmod1003_min_passwd_age = (86400 * 30); /* once a month */
+ buffer = (uint8_t *)&u1003;
+ break;
+ case 1004:
+ u1004.usrmod1004_force_logoff = TIMEQ_FOREVER;
+ buffer = (uint8_t *)&u1004;
+ break;
+ case 1005:
+ u1005.usrmod1005_password_hist_len = 0;
+ buffer = (uint8_t *)&u1005;
+ break;
+ case 1006:
+ case 1007:
+ default:
+ break;
+ }
+
+ /* NetUserModalsSet */
+
+ status = NetUserModalsSet(hostname,
+ level,
+ buffer,
+ &parm_err);
+ if (status != 0) {
+ printf("NetUserModalsSet failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_setgroups.c b/source3/lib/netapi/examples/user/user_setgroups.c
new file mode 100644
index 0000000..de3ff22
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_setgroups.c
@@ -0,0 +1,144 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserSetGroups query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint32_t level = 0;
+ uint8_t *buffer = NULL;
+ uint32_t num_entries = 0;
+ const char **names = NULL;
+ int i = 0;
+ size_t buf_size = 0;
+
+ struct GROUP_USERS_INFO_0 *g0 = NULL;
+ struct GROUP_USERS_INFO_1 *g1 = NULL;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_setgroups", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username group1 group2 ...");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+
+ names = poptGetArgs(pc);
+ for (i=0; names[i] != NULL; i++) {
+ num_entries++;
+ }
+
+ switch (level) {
+ case 0:
+ buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g0);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g0[i].grui0_name = names[i];
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 1:
+ buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g1);
+ if (status) {
+ printf("NetApiBufferAllocate failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g1[i].grui1_name = names[i];
+ g1[i].grui1_attributes = 0; /* ? */
+ }
+
+ buffer = (uint8_t *)g1;
+ break;
+ default:
+ break;
+ }
+
+ /* NetUserSetGroups */
+
+ status = NetUserSetGroups(hostname,
+ username,
+ level,
+ buffer,
+ num_entries);
+ if (status != 0) {
+ printf("NetUserSetGroups failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ out:
+ NetApiBufferFree(buffer);
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/user/user_setinfo.c b/source3/lib/netapi/examples/user/user_setinfo.c
new file mode 100644
index 0000000..56c9822
--- /dev/null
+++ b/source3/lib/netapi/examples/user/user_setinfo.c
@@ -0,0 +1,200 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetUserSetInfo query
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+int main(int argc, const char **argv)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx = NULL;
+ const char *hostname = NULL;
+ const char *username = NULL;
+ uint32_t level = 0;
+ uint32_t parm_err = 0;
+ uint8_t *buffer = NULL;
+ const char *val = NULL;
+
+ struct USER_INFO_0 u0;
+ struct USER_INFO_1003 u1003;
+ struct USER_INFO_1005 u1005;
+ struct USER_INFO_1006 u1006;
+ struct USER_INFO_1007 u1007;
+ struct USER_INFO_1008 u1008;
+ struct USER_INFO_1009 u1009;
+ struct USER_INFO_1010 u1010;
+ struct USER_INFO_1011 u1011;
+ struct USER_INFO_1012 u1012;
+ struct USER_INFO_1014 u1014;
+ struct USER_INFO_1017 u1017;
+ struct USER_INFO_1024 u1024;
+ struct USER_INFO_1051 u1051;
+ struct USER_INFO_1052 u1052;
+ struct USER_INFO_1053 u1053;
+
+ poptContext pc;
+ int opt;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ POPT_COMMON_LIBNETAPI_EXAMPLES
+ POPT_TABLEEND
+ };
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return status;
+ }
+
+ pc = poptGetContext("user_setinfo", argc, argv, long_options, 0);
+
+ poptSetOtherOptionHelp(pc, "hostname username level");
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ }
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ hostname = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ username = poptGetArg(pc);
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ level = atoi(poptGetArg(pc));
+
+ if (!poptPeekArg(pc)) {
+ poptPrintHelp(pc, stderr, 0);
+ goto out;
+ }
+ val = poptGetArg(pc);
+
+ /* NetUserSetInfo */
+
+ switch (level) {
+ case 0:
+ u0.usri0_name = val;
+ buffer = (uint8_t *)&u0;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ case 21:
+ break;
+ case 22:
+ break;
+ case 1003:
+ u1003.usri1003_password = val;
+ buffer = (uint8_t *)&u1003;
+ break;
+ case 1005:
+ u1005.usri1005_priv = atoi(val);
+ buffer = (uint8_t *)&u1005;
+ break;
+ case 1006:
+ u1006.usri1006_home_dir = val;
+ buffer = (uint8_t *)&u1006;
+ break;
+ case 1007:
+ u1007.usri1007_comment = val;
+ buffer = (uint8_t *)&u1007;
+ break;
+ case 1008:
+ u1008.usri1008_flags = atoi(val);
+ buffer = (uint8_t *)&u1008;
+ break;
+ case 1009:
+ u1009.usri1009_script_path = val;
+ buffer = (uint8_t *)&u1009;
+ break;
+ case 1010:
+ u1010.usri1010_auth_flags = atoi(val);
+ buffer = (uint8_t *)&u1010;
+ break;
+ case 1011:
+ u1011.usri1011_full_name = val;
+ buffer = (uint8_t *)&u1011;
+ break;
+ case 1012:
+ u1012.usri1012_usr_comment = val;
+ buffer = (uint8_t *)&u1012;
+ break;
+ case 1014:
+ u1014.usri1014_workstations = val;
+ buffer = (uint8_t *)&u1014;
+ break;
+ case 1017:
+ u1017.usri1017_acct_expires = atoi(val);
+ buffer = (uint8_t *)&u1017;
+ break;
+ case 1020:
+ break;
+ case 1024:
+ u1024.usri1024_country_code = atoi(val);
+ buffer = (uint8_t *)&u1024;
+ break;
+ case 1051:
+ u1051.usri1051_primary_group_id = atoi(val);
+ buffer = (uint8_t *)&u1051;
+ break;
+ case 1052:
+ u1052.usri1052_profile = val;
+ buffer = (uint8_t *)&u1052;
+ break;
+ case 1053:
+ u1053.usri1053_home_dir_drive = val;
+ buffer = (uint8_t *)&u1053;
+ break;
+ default:
+ break;
+ }
+
+ status = NetUserSetInfo(hostname,
+ username,
+ level,
+ buffer,
+ &parm_err);
+ if (status != 0) {
+ printf("NetUserSetInfo failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ goto out;
+ }
+
+ out:
+ libnetapi_free(ctx);
+ poptFreeContext(pc);
+
+ return status;
+}
diff --git a/source3/lib/netapi/examples/wscript_build b/source3/lib/netapi/examples/wscript_build
new file mode 100644
index 0000000..1d56840
--- /dev/null
+++ b/source3/lib/netapi/examples/wscript_build
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+# The remaining task is to build the gtk example, but we first need to find the gtk libs
+# netdomjoin-gui/netdomjoin-gui.c
+
+names = [
+ ("getdc", "getdc"),
+ ("dsgetdc", "dsgetdc"),
+ ("join", "netdomjoin"),
+ ("join", "getjoinableous"),
+ ("join", "getjoininformation"),
+ ("join", "rename_machine"),
+ ("join", "provision_computer_account"),
+ ("join", "request_offline_domain_join"),
+ ("join", "djoin"),
+ ("user", "user_add"),
+ ("user", "user_del"),
+ ("user", "user_enum"),
+ ("user", "user_dispinfo"),
+ ("user", "user_chgpwd"),
+ ("user", "user_getinfo"),
+ ("user", "user_setinfo"),
+ ("user", "user_modalsget"),
+ ("user", "user_modalsset"),
+ ("user", "user_getgroups"),
+ ("user", "user_setgroups"),
+ ("user", "user_getlocalgroups"),
+ ("group", "group_add"),
+ ("group", "group_del"),
+ ("group", "group_enum"),
+ ("group", "group_setinfo"),
+ ("group", "group_getinfo"),
+ ("group", "group_adduser"),
+ ("group", "group_deluser"),
+ ("group", "group_getusers"),
+ ("group", "group_setusers"),
+ ("localgroup", "localgroup_add"),
+ ("localgroup", "localgroup_del"),
+ ("localgroup", "localgroup_getinfo"),
+ ("localgroup", "localgroup_setinfo"),
+ ("localgroup", "localgroup_enum"),
+ ("localgroup", "localgroup_addmembers"),
+ ("localgroup", "localgroup_delmembers"),
+ ("localgroup", "localgroup_setmembers"),
+ ("localgroup", "localgroup_getmembers"),
+ ("server", "remote_tod"),
+ ("server", "server_getinfo"),
+ ("share", "share_add"),
+ ("share", "share_del"),
+ ("share", "share_enum"),
+ ("share", "share_getinfo"),
+ ("share", "share_setinfo"),
+ ("file", "file_close"),
+ ("file", "file_getinfo"),
+ ("file", "file_enum"),
+ ("shutdown", "shutdown_init"),
+ ("shutdown", "shutdown_abort"),
+ ("netlogon", "netlogon_control"),
+ ("netlogon", "netlogon_control2"),
+ ("netlogon", "nltest")]
+
+
+bld.SAMBA_SUBSYSTEM('LIBNETAPI_EXAMPLES_COMMON',
+ source='common.c',
+ deps='netapi popt')
+
+for pattern in names:
+ (subdir, name) = pattern
+ bld.SAMBA_BINARY('%s/%s' % (subdir, name),
+ source='%s/%s.c' % (subdir, name),
+ deps='netapi popt LIBNETAPI_EXAMPLES_COMMON',
+ install=False)