schannel_tdb: make code compilable in both trees
authorSimo Sorce <idra@samba.org>
Thu, 18 Feb 2010 21:17:06 +0000 (16:17 -0500)
committerSimo Sorce <idra@samba.org>
Tue, 23 Feb 2010 17:46:50 +0000 (12:46 -0500)
libcli/auth/schannel_state.h
libcli/auth/schannel_state_tdb.c
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_pipe.c

index c1fa1245cf55cdd25aeb2b2d5cffc973d52e1d31..8db0698a9d75e3ad02ecb90e6453368568397d01 100644 (file)
 #define _LIBCLI_AUTH_SCHANNEL_STATE_H__
 
 NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
 #define _LIBCLI_AUTH_SCHANNEL_STATE_H__
 
 NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+                                 struct smb_iconv_convenience *ic,
+                                 const char *db_priv_dir,
                                  const char *computer_name,
                                  struct netlogon_creds_CredentialState **creds);
 
 NTSTATUS schannel_save_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 smb_iconv_convenience *ic,
+                                  const char *db_priv_dir,
                                   struct netlogon_creds_CredentialState *creds);
 
 NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
                                   struct netlogon_creds_CredentialState *creds);
 
 NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+                                   struct smb_iconv_convenience *ic,
+                                   const char *db_priv_dir,
                                    const char *computer_name,
                                    struct netr_Authenticator *received_authenticator,
                                    struct netr_Authenticator *return_authenticator,
                                    const char *computer_name,
                                    struct netr_Authenticator *received_authenticator,
                                    struct netr_Authenticator *return_authenticator,
index 434d7d7f8cfaa486b9d9aa22a3e40897c63e48e5..fd61b0a38a8350e73ae0cdaae9875fa6b6bd57a9 100644 (file)
 */
 
 #include "includes.h"
 */
 
 #include "includes.h"
+#include "system/filesys.h"
+#include <tdb.h>
+#include "../lib/util/util_tdb.h"
 #include "../libcli/auth/libcli_auth.h"
 #include "../libcli/auth/schannel_state.h"
 #include "../librpc/gen_ndr/ndr_schannel.h"
 #include "../libcli/auth/libcli_auth.h"
 #include "../libcli/auth/schannel_state.h"
 #include "../librpc/gen_ndr/ndr_schannel.h"
+#if _SAMBA_BUILD_ == 4
+#include "tdb_wrap.h"
+#endif
 
 #define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
 
 
 #define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
 
 #define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
 #define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_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)
+static struct tdb_wrap *open_schannel_session_store(TALLOC_CTX *mem_ctx,
+                                                   const char *private_dir)
 {
        TDB_DATA vers;
 {
        TDB_DATA vers;
-       uint32 ver;
-       TDB_CONTEXT *tdb_sc = NULL;
-       char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
+       uint32_t ver;
+       struct tdb_wrap *tdb_sc = NULL;
+       char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", private_dir);
 
        if (!fname) {
                return NULL;
        }
 
 
        if (!fname) {
                return NULL;
        }
 
-       tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+       tdb_sc = tdb_wrap_open(mem_ctx, fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
 
        if (!tdb_sc) {
                DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
 
        if (!tdb_sc) {
                DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
@@ -56,31 +63,29 @@ static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
        }
 
  again:
        }
 
  again:
-       vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
+       vers = tdb_fetch_bystring(tdb_sc->tdb, "SCHANNEL_STORE_VERSION");
        if (vers.dptr == NULL) {
                /* First opener, no version. */
                SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
        if (vers.dptr == NULL) {
                /* First opener, no version. */
                SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
-               vers.dptr = (uint8 *)&ver;
+               vers.dptr = (uint8_t *)&ver;
                vers.dsize = 4;
                vers.dsize = 4;
-               tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
+               tdb_store_bystring(tdb_sc->tdb, "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 ));
                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);
+                       tdb_wipe_all(tdb_sc->tdb);
                        goto again;
                }
                if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
                        DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
                                (int)ver, fname ));
                        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;
+                       TALLOC_FREE(tdb_sc);
                }
        } else {
                }
        } else {
-               tdb_close(tdb_sc);
-               tdb_sc = NULL;
+               TALLOC_FREE(tdb_sc);
                DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
                        (int)vers.dsize, fname ));
        }
                DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
                        (int)vers.dsize, fname ));
        }
@@ -95,8 +100,9 @@ static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
  ********************************************************************/
 
 static
  ********************************************************************/
 
 static
-NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
+NTSTATUS schannel_store_session_key_tdb(struct tdb_wrap *tdb_sc,
                                        TALLOC_CTX *mem_ctx,
                                        TALLOC_CTX *mem_ctx,
+                                       struct smb_iconv_convenience *ic,
                                        struct netlogon_creds_CredentialState *creds)
 {
        enum ndr_err_code ndr_err;
                                        struct netlogon_creds_CredentialState *creds)
 {
        enum ndr_err_code ndr_err;
@@ -104,15 +110,21 @@ NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
        TDB_DATA value;
        int ret;
        char *keystr;
        TDB_DATA value;
        int ret;
        char *keystr;
+       char *name_upper;
 
 
-       keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
-                                           SECRETS_SCHANNEL_STATE,
-                                           creds->computer_name);
+       name_upper = strupper_talloc(mem_ctx, creds->computer_name);
+       if (!name_upper) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       keystr = talloc_asprintf(mem_ctx, "%s/%s",
+                                SECRETS_SCHANNEL_STATE, name_upper);
+       TALLOC_FREE(name_upper);
        if (!keystr) {
                return NT_STATUS_NO_MEMORY;
        }
 
        if (!keystr) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, creds,
+       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, ic, creds,
                        (ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                talloc_free(keystr);
                        (ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                talloc_free(keystr);
@@ -122,10 +134,10 @@ NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
        value.dptr = blob.data;
        value.dsize = blob.length;
 
        value.dptr = blob.data;
        value.dsize = blob.length;
 
-       ret = tdb_store_bystring(tdb, keystr, value, TDB_REPLACE);
+       ret = tdb_store_bystring(tdb_sc->tdb, keystr, value, TDB_REPLACE);
        if (ret != TDB_SUCCESS) {
                DEBUG(0,("Unable to add %s to session key db - %s\n",
        if (ret != TDB_SUCCESS) {
                DEBUG(0,("Unable to add %s to session key db - %s\n",
-                        keystr, tdb_errorstr(tdb)));
+                        keystr, tdb_errorstr(tdb_sc->tdb)));
                talloc_free(keystr);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
                talloc_free(keystr);
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
@@ -146,8 +158,9 @@ NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
  ********************************************************************/
 
 static
  ********************************************************************/
 
 static
-NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
+NTSTATUS schannel_fetch_session_key_tdb(struct tdb_wrap *tdb_sc,
                                        TALLOC_CTX *mem_ctx,
                                        TALLOC_CTX *mem_ctx,
+                                       struct smb_iconv_convenience *ic,
                                        const char *computer_name,
                                        struct netlogon_creds_CredentialState **pcreds)
 {
                                        const char *computer_name,
                                        struct netlogon_creds_CredentialState **pcreds)
 {
@@ -157,18 +170,24 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
        DATA_BLOB blob;
        struct netlogon_creds_CredentialState *creds = NULL;
        char *keystr = NULL;
        DATA_BLOB blob;
        struct netlogon_creds_CredentialState *creds = NULL;
        char *keystr = NULL;
+       char *name_upper;
 
        *pcreds = NULL;
 
 
        *pcreds = NULL;
 
-       keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
-                                           SECRETS_SCHANNEL_STATE,
-                                           computer_name);
+       name_upper = strupper_talloc(mem_ctx, computer_name);
+       if (!name_upper) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       keystr = talloc_asprintf(mem_ctx, "%s/%s",
+                                SECRETS_SCHANNEL_STATE, name_upper);
+       TALLOC_FREE(name_upper);
        if (!keystr) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
        if (!keystr) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
-       value = tdb_fetch_bystring(tdb, keystr);
+       value = tdb_fetch_bystring(tdb_sc->tdb, keystr);
        if (!value.dptr) {
                DEBUG(0,("schannel_fetch_session_key_tdb: Failed to find entry with key %s\n",
                        keystr ));
        if (!value.dptr) {
                DEBUG(0,("schannel_fetch_session_key_tdb: Failed to find entry with key %s\n",
                        keystr ));
@@ -184,7 +203,7 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 
        blob = data_blob_const(value.dptr, value.dsize);
 
 
        blob = data_blob_const(value.dptr, value.dsize);
 
-       ndr_err = ndr_pull_struct_blob(&blob, creds, NULL, creds,
+       ndr_err = ndr_pull_struct_blob(&blob, creds, ic, creds,
                        (ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                status = ndr_map_error2ntstatus(ndr_err);
                        (ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                status = ndr_map_error2ntstatus(ndr_err);
@@ -220,22 +239,36 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 *******************************************************************************/
 
 NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
 *******************************************************************************/
 
 NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+                                 struct smb_iconv_convenience *ic,
+                                 const char *db_priv_dir,
                                  const char *computer_name,
                                  const char *computer_name,
-                                 struct netlogon_creds_CredentialState **creds)
+                                 struct netlogon_creds_CredentialState **_creds)
 {
 {
-       struct tdb_context *tdb;
+       TALLOC_CTX *tmpctx;
+       struct tdb_wrap *tdb_sc;
+       struct netlogon_creds_CredentialState *creds;
        NTSTATUS status;
 
        NTSTATUS status;
 
-       tdb = open_schannel_session_store(mem_ctx);
-       if (!tdb) {
-               return NT_STATUS_ACCESS_DENIED;
+       tmpctx = talloc_named(mem_ctx, 0, "schannel_get_creds_state");
+       if (!tmpctx) {
+               return NT_STATUS_NO_MEMORY;
        }
 
        }
 
-       status = schannel_fetch_session_key_tdb(tdb, mem_ctx,
-                                               computer_name, creds);
+       tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
+       if (!tdb_sc) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
 
-       tdb_close(tdb);
+       status = schannel_fetch_session_key_tdb(tdb_sc, tmpctx, ic,
+                                               computer_name, &creds);
+       if (NT_STATUS_IS_OK(status)) {
+               *_creds = talloc_steal(mem_ctx, creds);
+               if (!*_creds) {
+                       status = NT_STATUS_NO_MEMORY;
+               }
+       }
 
 
+       talloc_free(tmpctx);
        return status;
 }
 
        return status;
 }
 
@@ -245,20 +278,27 @@ NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
 *******************************************************************************/
 
 NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
 *******************************************************************************/
 
 NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
+                                  struct smb_iconv_convenience *ic,
+                                  const char *db_priv_dir,
                                   struct netlogon_creds_CredentialState *creds)
 {
                                   struct netlogon_creds_CredentialState *creds)
 {
-       struct tdb_context *tdb;
+       TALLOC_CTX *tmpctx;
+       struct tdb_wrap *tdb_sc;
        NTSTATUS status;
 
        NTSTATUS status;
 
-       tdb = open_schannel_session_store(mem_ctx);
-       if (!tdb) {
-               return NT_STATUS_ACCESS_DENIED;
+       tmpctx = talloc_named(mem_ctx, 0, "schannel_save_creds_state");
+       if (!tmpctx) {
+               return NT_STATUS_NO_MEMORY;
        }
 
        }
 
-       status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
+       tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
+       if (!tdb_sc) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
 
 
-       tdb_close(tdb);
+       status = schannel_store_session_key_tdb(tdb_sc, tmpctx, ic, creds);
 
 
+       talloc_free(tmpctx);
        return status;
 }
 
        return status;
 }
 
@@ -273,13 +313,15 @@ NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+                                   struct smb_iconv_convenience *ic,
+                                   const char *db_priv_dir,
                                    const char *computer_name,
                                    struct netr_Authenticator *received_authenticator,
                                    struct netr_Authenticator *return_authenticator,
                                    struct netlogon_creds_CredentialState **creds_out)
 {
        TALLOC_CTX *tmpctx;
                                    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 tdb_wrap *tdb_sc;
        struct netlogon_creds_CredentialState *creds;
        NTSTATUS status;
        int ret;
        struct netlogon_creds_CredentialState *creds;
        NTSTATUS status;
        int ret;
@@ -289,13 +331,13 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
                return NT_STATUS_NO_MEMORY;
        }
 
-       tdb = open_schannel_session_store(tmpctx);
-       if (!tdb) {
+       tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
+       if (!tdb_sc) {
                status = NT_STATUS_ACCESS_DENIED;
                goto done;
        }
 
                status = NT_STATUS_ACCESS_DENIED;
                goto done;
        }
 
-       ret = tdb_transaction_start(tdb);
+       ret = tdb_transaction_start(tdb_sc->tdb);
        if (ret != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
                status = NT_STATUS_INTERNAL_DB_CORRUPTION;
        if (ret != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
                status = NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -306,10 +348,10 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
         * disconnects) we must update the database every time we
         * update the structure */
 
         * disconnects) we must update the database every time we
         * update the structure */
 
-       status = schannel_fetch_session_key_tdb(tdb, tmpctx,
+       status = schannel_fetch_session_key_tdb(tdb_sc, tmpctx, ic,
                                                computer_name, &creds);
        if (!NT_STATUS_IS_OK(status)) {
                                                computer_name, &creds);
        if (!NT_STATUS_IS_OK(status)) {
-               tdb_transaction_cancel(tdb);
+               tdb_transaction_cancel(tdb_sc->tdb);
                goto done;
        }
 
                goto done;
        }
 
@@ -317,17 +359,17 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
                                                  received_authenticator,
                                                  return_authenticator);
        if (!NT_STATUS_IS_OK(status)) {
                                                  received_authenticator,
                                                  return_authenticator);
        if (!NT_STATUS_IS_OK(status)) {
-               tdb_transaction_cancel(tdb);
+               tdb_transaction_cancel(tdb_sc->tdb);
                goto done;
        }
 
                goto done;
        }
 
-       status = schannel_store_session_key_tdb(tdb, tmpctx, creds);
+       status = schannel_store_session_key_tdb(tdb_sc, tmpctx, ic, creds);
        if (!NT_STATUS_IS_OK(status)) {
        if (!NT_STATUS_IS_OK(status)) {
-               tdb_transaction_cancel(tdb);
+               tdb_transaction_cancel(tdb_sc->tdb);
                goto done;
        }
 
                goto done;
        }
 
-       tdb_transaction_commit(tdb);
+       tdb_transaction_commit(tdb_sc->tdb);
 
        if (creds_out) {
                *creds_out = talloc_steal(mem_ctx, creds);
 
        if (creds_out) {
                *creds_out = talloc_steal(mem_ctx, creds);
@@ -341,7 +383,6 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
 
 done:
        talloc_free(tmpctx);
 
 done:
        talloc_free(tmpctx);
-       if (tdb) tdb_close(tdb);
        return status;
 }
 
        return status;
 }
 
index 15f19b5207442f6c9f39329d24e77fa052665474..b9bfda9a83bbbaa6c062f28a9825d088a7be2760 100644 (file)
@@ -724,7 +724,8 @@ 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_save_creds_state(p->mem_ctx, creds);
+       status = schannel_save_creds_state(p->mem_ctx,
+                                          NULL, lp_private_dir(), creds);
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -817,7 +818,8 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
                }
        }
 
                }
        }
 
-       status = schannel_check_creds_state(mem_ctx,
+       status = schannel_check_creds_state(mem_ctx, NULL,
+                                           lp_private_dir(),
                                            computer_name,
                                            received_authenticator,
                                            return_authenticator,
                                            computer_name,
                                            received_authenticator,
                                            return_authenticator,
@@ -1387,6 +1389,7 @@ NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p,
 
        become_root();
        status = schannel_get_creds_state(p->mem_ctx,
 
        become_root();
        status = schannel_get_creds_state(p->mem_ctx,
+                                         NULL, lp_private_dir(),
                                          r->in.computer_name, &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
                                          r->in.computer_name, &creds);
        unbecome_root();
        if (!NT_STATUS_IS_OK(status)) {
index 5cde423dafc0046b590e0a3c8c34593881251897..d65f52e4b3c8af3420cb516b7f8f51d7c7f341ab 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_get_creds_state(p,
+       status = schannel_get_creds_state(p, NULL, lp_private_dir(),
                                            neg.oem_netbios_computer.a,
                                            &creds);
        unbecome_root();
                                            neg.oem_netbios_computer.a,
                                            &creds);
        unbecome_root();