s3:schannel streamline interface
authorSimo Sorce <idra@samba.org>
Thu, 18 Feb 2010 19:44:09 +0000 (14:44 -0500)
committerSimo Sorce <idra@samba.org>
Tue, 23 Feb 2010 17:46:50 +0000 (12:46 -0500)
Make calling schannel much easier by removing the need to explicitly open the
database. Let the abstraction do it instead.

libcli/auth/schannel_state.h
libcli/auth/schannel_state_tdb.c
source3/Makefile.in
source3/include/proto.h
source3/include/secrets.h
source3/passdb/secrets_schannel.c [deleted file]
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_pipe.c

index efa8d20b0867ee87135122648e5e6d82b6d93e02..c1fa1245cf55cdd25aeb2b2d5cffc973d52e1d31 100644 (file)
 #ifndef _LIBCLI_AUTH_SCHANNEL_STATE_H__
 #define _LIBCLI_AUTH_SCHANNEL_STATE_H__
 
 #ifndef _LIBCLI_AUTH_SCHANNEL_STATE_H__
 #define _LIBCLI_AUTH_SCHANNEL_STATE_H__
 
+NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+                                 const char *computer_name,
+                                 struct netlogon_creds_CredentialState **creds);
+
+NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
+                                  struct netlogon_creds_CredentialState *creds);
+
+NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+                                   const char *computer_name,
+                                   struct netr_Authenticator *received_authenticator,
+                                   struct netr_Authenticator *return_authenticator,
+                                   struct netlogon_creds_CredentialState **creds_out);
+
 struct ldb_context;
 struct ldb_context;
-struct tdb_context;
 
 NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb,
                                        TALLOC_CTX *mem_ctx,
 
 NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb,
                                        TALLOC_CTX *mem_ctx,
@@ -39,17 +51,4 @@ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
                                              struct netr_Authenticator *received_authenticator,
                                              struct netr_Authenticator *return_authenticator,
                                              struct netlogon_creds_CredentialState **creds_out);
                                              struct netr_Authenticator *received_authenticator,
                                              struct netr_Authenticator *return_authenticator,
                                              struct netlogon_creds_CredentialState **creds_out);
-NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
-                                       TALLOC_CTX *mem_ctx,
-                                       struct netlogon_creds_CredentialState *creds);
-NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
-                                       TALLOC_CTX *mem_ctx,
-                                       const char *computer_name,
-                                       struct netlogon_creds_CredentialState **creds);
-NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
-                                             TALLOC_CTX *mem_ctx,
-                                             const char *computer_name,
-                                             struct netr_Authenticator *received_authenticator,
-                                             struct netr_Authenticator *return_authenticator,
-                                             struct netlogon_creds_CredentialState **creds_out);
 #endif
 #endif
index 49c89085be2a0340c59d11350a20e92424dd078b..434d7d7f8cfaa486b9d9aa22a3e40897c63e48e5 100644 (file)
 #include "../libcli/auth/schannel_state.h"
 #include "../librpc/gen_ndr/ndr_schannel.h"
 
 #include "../libcli/auth/schannel_state.h"
 #include "../librpc/gen_ndr/ndr_schannel.h"
 
+#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
+
+/******************************************************************************
+ Open or create the schannel session store tdb.
+*******************************************************************************/
+
+#define SCHANNEL_STORE_VERSION_1 1
+#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
+#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
+
+static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
+{
+       TDB_DATA vers;
+       uint32 ver;
+       TDB_CONTEXT *tdb_sc = NULL;
+       char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
+
+       if (!fname) {
+               return NULL;
+       }
+
+       tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+
+       if (!tdb_sc) {
+               DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
+               TALLOC_FREE(fname);
+               return NULL;
+       }
+
+ again:
+       vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
+       if (vers.dptr == NULL) {
+               /* First opener, no version. */
+               SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
+               vers.dptr = (uint8 *)&ver;
+               vers.dsize = 4;
+               tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
+               vers.dptr = NULL;
+       } else if (vers.dsize == 4) {
+               ver = IVAL(vers.dptr,0);
+               if (ver == SCHANNEL_STORE_VERSION_2) {
+                       DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
+                               (int)ver, fname ));
+                       tdb_wipe_all(tdb_sc);
+                       goto again;
+               }
+               if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
+                       DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
+                               (int)ver, fname ));
+                       tdb_close(tdb_sc);
+                       tdb_sc = NULL;
+               }
+       } else {
+               tdb_close(tdb_sc);
+               tdb_sc = NULL;
+               DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
+                       (int)vers.dsize, fname ));
+       }
+
+       SAFE_FREE(vers.dptr);
+       TALLOC_FREE(fname);
+
+       return tdb_sc;
+}
+
 /********************************************************************
  ********************************************************************/
 
 /********************************************************************
  ********************************************************************/
 
+static
 NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
                                        TALLOC_CTX *mem_ctx,
                                        struct netlogon_creds_CredentialState *creds)
 NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
                                        TALLOC_CTX *mem_ctx,
                                        struct netlogon_creds_CredentialState *creds)
@@ -79,6 +145,7 @@ NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
 /********************************************************************
  ********************************************************************/
 
 /********************************************************************
  ********************************************************************/
 
+static
 NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
                                        TALLOC_CTX *mem_ctx,
                                        const char *computer_name,
 NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
                                        TALLOC_CTX *mem_ctx,
                                        const char *computer_name,
@@ -147,61 +214,134 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
-/********************************************************************
+/******************************************************************************
+ Wrapper around schannel_fetch_session_key_tdb()
+ Note we must be root here.
+*******************************************************************************/
+
+NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+                                 const char *computer_name,
+                                 struct netlogon_creds_CredentialState **creds)
+{
+       struct tdb_context *tdb;
+       NTSTATUS status;
+
+       tdb = open_schannel_session_store(mem_ctx);
+       if (!tdb) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
 
-  Validate an incoming authenticator against the credentials for the remote
-  machine.
+       status = schannel_fetch_session_key_tdb(tdb, mem_ctx,
+                                               computer_name, creds);
 
 
-  The credentials are (re)read and from the schannel database, and
-  written back after the caclulations are performed.
+       tdb_close(tdb);
 
 
-  The creds_out parameter (if not NULL) returns the credentials, if
-  the caller needs some of that information.
+       return status;
+}
+
+/******************************************************************************
+ Wrapper around schannel_store_session_key_tdb()
+ Note we must be root here.
+*******************************************************************************/
+
+NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
+                                  struct netlogon_creds_CredentialState *creds)
+{
+       struct tdb_context *tdb;
+       NTSTATUS status;
+
+       tdb = open_schannel_session_store(mem_ctx);
+       if (!tdb) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
 
+       status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
+
+       tdb_close(tdb);
+
+       return status;
+}
+
+/********************************************************************
+ Validate an incoming authenticator against the credentials for the
+ remote machine stored in the schannel database.
+
+ The credentials are (re)read and from the schannel database, and
+ written back after the caclulations are performed.
+
+ If the creds_out parameter is not NULL returns the credentials.
  ********************************************************************/
 
  ********************************************************************/
 
-NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
-                                             TALLOC_CTX *mem_ctx,
-                                             const char *computer_name,
-                                             struct netr_Authenticator *received_authenticator,
-                                             struct netr_Authenticator *return_authenticator,
-                                             struct netlogon_creds_CredentialState **creds_out)
+NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+                                   const char *computer_name,
+                                   struct netr_Authenticator *received_authenticator,
+                                   struct netr_Authenticator *return_authenticator,
+                                   struct netlogon_creds_CredentialState **creds_out)
 {
 {
+       TALLOC_CTX *tmpctx;
+       struct tdb_context *tdb;
        struct netlogon_creds_CredentialState *creds;
        NTSTATUS status;
        int ret;
 
        struct netlogon_creds_CredentialState *creds;
        NTSTATUS status;
        int ret;
 
+       tmpctx = talloc_named(mem_ctx, 0, "schannel_check_creds_state");
+       if (!tmpctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       tdb = open_schannel_session_store(tmpctx);
+       if (!tdb) {
+               status = NT_STATUS_ACCESS_DENIED;
+               goto done;
+       }
+
        ret = tdb_transaction_start(tdb);
        if (ret != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        ret = tdb_transaction_start(tdb);
        if (ret != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
+               status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+               goto done;
        }
 
        /* Because this is a shared structure (even across
         * disconnects) we must update the database every time we
         * update the structure */
 
        }
 
        /* Because this is a shared structure (even across
         * disconnects) we must update the database every time we
         * update the structure */
 
-       status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name,
-                                               &creds);
+       status = schannel_fetch_session_key_tdb(tdb, tmpctx,
+                                               computer_name, &creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               tdb_transaction_cancel(tdb);
+               goto done;
+       }
 
 
-       if (NT_STATUS_IS_OK(status)) {
-               status = netlogon_creds_server_step_check(creds,
-                                                         received_authenticator,
-                                                         return_authenticator);
+       status = netlogon_creds_server_step_check(creds,
+                                                 received_authenticator,
+                                                 return_authenticator);
+       if (!NT_STATUS_IS_OK(status)) {
+               tdb_transaction_cancel(tdb);
+               goto done;
        }
 
        }
 
-       if (NT_STATUS_IS_OK(status)) {
-               status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
+       status = schannel_store_session_key_tdb(tdb, tmpctx, creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               tdb_transaction_cancel(tdb);
+               goto done;
        }
 
        }
 
-       if (NT_STATUS_IS_OK(status)) {
-               tdb_transaction_commit(tdb);
-               if (creds_out) {
-                       *creds_out = creds;
-                       talloc_steal(mem_ctx, creds);
+       tdb_transaction_commit(tdb);
+
+       if (creds_out) {
+               *creds_out = talloc_steal(mem_ctx, creds);
+               if (!*creds_out) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto done;
                }
                }
-       } else {
-               tdb_transaction_cancel(tdb);
        }
 
        }
 
+       status = NT_STATUS_OK;
+
+done:
+       talloc_free(tmpctx);
+       if (tdb) tdb_close(tdb);
        return status;
 }
        return status;
 }
+
index e966023a1ab5078e53a5e12b532dfabc9c782b8d..6e40f8362f68703c749aa3d4fc07ddcfb7185f2b 100644 (file)
@@ -508,8 +508,7 @@ SCHANNEL_OBJ = ../libcli/auth/credentials.o \
               ../libcli/auth/schannel_sign.o \
               ../libcli/auth/schannel_state_tdb.o \
               ../librpc/gen_ndr/ndr_schannel.o \
               ../libcli/auth/schannel_sign.o \
               ../libcli/auth/schannel_state_tdb.o \
               ../librpc/gen_ndr/ndr_schannel.o \
-              ../librpc/ndr/ndr_schannel.o \
-              passdb/secrets_schannel.o
+              ../librpc/ndr/ndr_schannel.o
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
             libsmb/clikrb5.o libsmb/clispnego.o \
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
             libsmb/clikrb5.o libsmb/clispnego.o \
index f8c3032ff13137e4b55997d72beeeab587304f5b..be932a960dbae502dd9b232c4f27417226ecff7d 100644 (file)
@@ -4746,15 +4746,6 @@ bool secrets_delete_generic(const char *owner, const char *key);
 bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]);
 
 bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]);
 
-/* The following definitions come from passdb/secrets_schannel.c  */
-
-TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx);
-NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
-                                   const char *computer_name,
-                                   struct netlogon_creds_CredentialState **pcreds);
-NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
-                                   struct netlogon_creds_CredentialState *creds);
-
 /* The following definitions come from passdb/util_builtin.c  */
 
 bool lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name);
 /* The following definitions come from passdb/util_builtin.c  */
 
 bool lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name);
index f369379c7014cb778ddba8e9f23cd5bbe3817087..d0848bdfa4a2cf67bf2000ecbc2b045f3ed60968 100644 (file)
@@ -87,6 +87,4 @@ struct afs_keyfile {
 
 #define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE"
 
 
 #define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE"
 
-#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
-
 #endif /* _SECRETS_H */
 #endif /* _SECRETS_H */
diff --git a/source3/passdb/secrets_schannel.c b/source3/passdb/secrets_schannel.c
deleted file mode 100644 (file)
index f4da625..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   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 "includes.h"
-#include "../libcli/auth/libcli_auth.h"
-#include "../libcli/auth/schannel_state.h"
-
-/******************************************************************************
- Open or create the schannel session store tdb.
-*******************************************************************************/
-
-#define SCHANNEL_STORE_VERSION_1 1
-#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
-#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
-
-TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
-{
-       TDB_DATA vers;
-       uint32 ver;
-       TDB_CONTEXT *tdb_sc = NULL;
-       char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
-
-       if (!fname) {
-               return NULL;
-       }
-
-       tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-
-       if (!tdb_sc) {
-               DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
-               TALLOC_FREE(fname);
-               return NULL;
-       }
-
- again:
-       vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
-       if (vers.dptr == NULL) {
-               /* First opener, no version. */
-               SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
-               vers.dptr = (uint8 *)&ver;
-               vers.dsize = 4;
-               tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
-               vers.dptr = NULL;
-       } else if (vers.dsize == 4) {
-               ver = IVAL(vers.dptr,0);
-               if (ver == SCHANNEL_STORE_VERSION_2) {
-                       DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
-                               (int)ver, fname ));
-                       tdb_wipe_all(tdb_sc);
-                       goto again;
-               }
-               if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
-                       DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
-                               (int)ver, fname ));
-                       tdb_close(tdb_sc);
-                       tdb_sc = NULL;
-               }
-       } else {
-               tdb_close(tdb_sc);
-               tdb_sc = NULL;
-               DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
-                       (int)vers.dsize, fname ));
-       }
-
-       SAFE_FREE(vers.dptr);
-       TALLOC_FREE(fname);
-
-       return tdb_sc;
-}
-
-/******************************************************************************
- Wrapper around schannel_fetch_session_key_tdb()
- Note we must be root here.
-*******************************************************************************/
-
-NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
-                                   const char *computer_name,
-                                   struct netlogon_creds_CredentialState **pcreds)
-{
-       struct tdb_context *tdb;
-       NTSTATUS status;
-
-       tdb = open_schannel_session_store(mem_ctx);
-       if (!tdb) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name, pcreds);
-
-       tdb_close(tdb);
-
-       return status;
-}
-
-/******************************************************************************
- Wrapper around schannel_store_session_key_tdb()
- Note we must be root here.
-*******************************************************************************/
-
-NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
-                                   struct netlogon_creds_CredentialState *creds)
-{
-       struct tdb_context *tdb;
-       NTSTATUS status;
-
-       tdb = open_schannel_session_store(mem_ctx);
-       if (!tdb) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
-
-       tdb_close(tdb);
-
-       return status;
-}
index 769936ca2000312fd43568b5fa64c41f2e57d451..15f19b5207442f6c9f39329d24e77fa052665474 100644 (file)
@@ -724,7 +724,7 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
 
        /* Store off the state so we can continue after client disconnect. */
        become_root();
 
        /* Store off the state so we can continue after client disconnect. */
        become_root();
-       status = schannel_store_session_key(p->mem_ctx, creds);
+       status = schannel_save_creds_state(p->mem_ctx, creds);
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -806,7 +806,6 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
                                             struct netlogon_creds_CredentialState **creds_out)
 {
        NTSTATUS status;
                                             struct netlogon_creds_CredentialState **creds_out)
 {
        NTSTATUS status;
-       struct tdb_context *tdb;
        bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
 
        if (schannel_global_required) {
        bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
 
        if (schannel_global_required) {
@@ -818,17 +817,11 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
                }
        }
 
                }
        }
 
-       tdb = open_schannel_session_store(mem_ctx);
-       if (!tdb) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       status = schannel_creds_server_step_check_tdb(tdb, mem_ctx,
-                                                     computer_name,
-                                                     received_authenticator,
-                                                     return_authenticator,
-                                                     creds_out);
-       tdb_close(tdb);
+       status = schannel_check_creds_state(mem_ctx,
+                                           computer_name,
+                                           received_authenticator,
+                                           return_authenticator,
+                                           creds_out);
 
        return status;
 }
 
        return status;
 }
@@ -1393,7 +1386,8 @@ NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p,
        struct netlogon_creds_CredentialState *creds = NULL;
 
        become_root();
        struct netlogon_creds_CredentialState *creds = NULL;
 
        become_root();
-       status = schannel_fetch_session_key(p->mem_ctx, r->in.computer_name, &creds);
+       status = schannel_get_creds_state(p->mem_ctx,
+                                         r->in.computer_name, &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                return status;
index 23f947f95bf9fcef05d0092e2454a7821120468b..5cde423dafc0046b590e0a3c8c34593881251897 100644 (file)
@@ -1477,7 +1477,7 @@ static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
         */
 
        become_root();
         */
 
        become_root();
-       status = schannel_fetch_session_key(p,
+       status = schannel_get_creds_state(p,
                                            neg.oem_netbios_computer.a,
                                            &creds);
        unbecome_root();
                                            neg.oem_netbios_computer.a,
                                            &creds);
        unbecome_root();